diff --git a/reactos/drivers/filesystems/cdfs_new/allocsup.c b/reactos/drivers/filesystems/cdfs_new/allocsup.c deleted file mode 100755 index 181d247a412..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/allocsup.c +++ /dev/null @@ -1,903 +0,0 @@ -/*++ - -Copyright (c) 1990-2000 Microsoft Corporation - -Module Name: - - AllocSup.c - -Abstract: - - This module implements the Allocation support routines for Cdfs. - - The data structure used here is the CD_MCB. There is an entry in - the Mcb for each dirent for a file. The entry will map the offset - within some file to a starting disk offset and number of bytes. - The Mcb also contains the interleave information for an extent. - An interleave consists of a number of blocks with data and a - (possibly different) number of blocks to skip. Any number of - data/skip pairs may exist in an extent but the data and skip sizes - are the same throughout the extent. - - We store the following information into an Mcb entry for an extent. - - FileOffset Offset in file for start of extent - DiskOffset Offset on disk for start of extent - ByteCount Number of file bytes in extent, no skip bytes - DataBlockByteCount Number of bytes in each data block - TotalBlockByteCount Number of bytes is data block and skip block - - The disk offset in the Mcb has already been biased by the size of - the Xar block if present. All of the byte count fields are aligned - on logical block boundaries. If this is a directory or path table - then the file offset has been biased to round the initial disk - offset down to a sector boundary. The biasing is done when loading - the values into an Mcb entry. - - An XA file has a header prepended to the file and each sector is 2352 - bytes. The allocation information ignores the header and only deals - with 2048 byte sectors. Callers into the allocation package have - adjusted the starting offset value to reflect 2048 sectors. On return - from this package the caller will have to convert from 2048 sector values - into raw XA sector values. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_ALLOCSUP) - -// -// Local support routines -// - -ULONG -CdFindMcbEntry ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG FileOffset - ); - -VOID -CdDiskOffsetFromMcbEntry ( - IN PIRP_CONTEXT IrpContext, - IN PCD_MCB_ENTRY McbEntry, - IN LONGLONG FileOffset, - IN PLONGLONG DiskOffset, - IN PULONG ByteCount - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdAddInitialAllocation) -#pragma alloc_text(PAGE, CdAddAllocationFromDirent) -#pragma alloc_text(PAGE, CdDiskOffsetFromMcbEntry) -#pragma alloc_text(PAGE, CdFindMcbEntry) -#pragma alloc_text(PAGE, CdInitializeMcb) -#pragma alloc_text(PAGE, CdLookupAllocation) -#pragma alloc_text(PAGE, CdTruncateAllocation) -#pragma alloc_text(PAGE, CdUninitializeMcb) -#endif - - -VOID -CdLookupAllocation ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG FileOffset, - OUT PLONGLONG DiskOffset, - OUT PULONG ByteCount - ) - -/*++ - -Routine Description: - - This routine looks through the mapping information for the file - to find the logical diskoffset and number of bytes at that offset. - We only deal with logical 2048 byte sectors here. - - If the mapping isn't present we will look it up on disk now. - This routine assumes we are looking up a valid range in the file. This - routine raises if it can't find mapping for the file offset. - - The Fcb may not be locked prior to calling this routine. We will always - acquire it here. - -Arguments: - - Fcb - Fcb representing this stream. - - FileOffset - Lookup the allocation beginning at this point. - - DiskOffset - Address to store the logical disk offset. - - ByteCount - Address to store the number of contiguous bytes beginning - at DiskOffset above. - -Return Value: - - None. - ---*/ - -{ - BOOLEAN FirstPass = TRUE; - ULONG McbEntryOffset; - PFCB ParentFcb = NULL; /* ReactOS Change: GCC uninitialized variable bug */ - BOOLEAN CleanupParent = FALSE; - - BOOLEAN UnlockFcb = FALSE; - - LONGLONG CurrentFileOffset; - ULONG CurrentMcbOffset; - PCD_MCB_ENTRY CurrentMcbEntry; - - DIRENT_ENUM_CONTEXT DirContext; - DIRENT Dirent; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - - // - // Use a try finally to facilitate cleanup. - // - - try { - - // - // We use a loop to perform the lookup. If we don't find the mapping in the - // first pass then we look up all of the allocation and then look again. - - while (TRUE) { - - // - // - // Lookup the entry containing this file offset. - // - - CdLockFcb( IrpContext, Fcb ); - UnlockFcb = TRUE; - - McbEntryOffset = CdFindMcbEntry( IrpContext, Fcb, FileOffset ); - - // - // If within the Mcb then we use the data out of this entry and are - // done. - // - - if (McbEntryOffset < Fcb->Mcb.CurrentEntryCount) { - - CdDiskOffsetFromMcbEntry( IrpContext, - Fcb->Mcb.McbArray + McbEntryOffset, - FileOffset, - DiskOffset, - ByteCount ); - - break; - - // - // If this is not the first pass then the disk is corrupt. - // - - } else if (!FirstPass) { - - CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); - } - - CdUnlockFcb( IrpContext, Fcb ); - UnlockFcb = FALSE; - - // - // Initialize the search dirent structures. - // - - CdInitializeDirContext( IrpContext, &DirContext ); - CdInitializeDirent( IrpContext, &Dirent ); - - // - // Otherwise we need to walk the dirents for this file until we find - // the one containing this entry. The parent Fcb should always be - // present. - // - - ParentFcb = Fcb->ParentFcb; - CdAcquireFileShared( IrpContext, ParentFcb ); - CleanupParent = TRUE; - - // - // Do an unsafe test to see if we need to create a file object. - // - - if (ParentFcb->FileObject == NULL) { - - CdCreateInternalStream( IrpContext, ParentFcb->Vcb, ParentFcb ); - } - - // - // Initialize the local variables to indicate the first dirent - // and lookup the first dirent. - // - - CurrentFileOffset = 0; - CurrentMcbOffset = 0; - - CdLookupDirent( IrpContext, - ParentFcb, - CdQueryFidDirentOffset( Fcb->FileId ), - &DirContext ); - - // - // If we are adding allocation to the Mcb then add all of it. - // - - while (TRUE ) { - - // - // Update the dirent from the on-disk dirent. - // - - CdUpdateDirentFromRawDirent( IrpContext, ParentFcb, &DirContext, &Dirent ); - - // - // Add this dirent to the Mcb if not already present. - // - - CdLockFcb( IrpContext, Fcb ); - UnlockFcb = TRUE; - - if (CurrentMcbOffset >= Fcb->Mcb.CurrentEntryCount) { - - CdAddAllocationFromDirent( IrpContext, Fcb, CurrentMcbOffset, CurrentFileOffset, &Dirent ); - } - - CdUnlockFcb( IrpContext, Fcb ); - UnlockFcb = FALSE; - - // - // If this is the last dirent for the file then exit. - // - - if (!FlagOn( Dirent.DirentFlags, CD_ATTRIBUTE_MULTI )) { - - break; - } - - // - // If we couldn't find another entry then the directory is corrupt because - // the last dirent for a file doesn't exist. - // - - if (!CdLookupNextDirent( IrpContext, ParentFcb, &DirContext, &DirContext )) { - - CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); - } - - // - // Update our loop variables. - // - - CurrentMcbEntry = Fcb->Mcb.McbArray + CurrentMcbOffset; - CurrentFileOffset += CurrentMcbEntry->ByteCount; - CurrentMcbOffset += 1; - } - - // - // All of the allocation is loaded. Go back and look up the mapping again. - // It better be there this time. - // - - FirstPass = FALSE; - } - - } finally { - - if (CleanupParent) { - - // - // Release the parent and cleanup the dirent structures. - // - - CdReleaseFile( IrpContext, ParentFcb ); - - CdCleanupDirContext( IrpContext, &DirContext ); - CdCleanupDirent( IrpContext, &Dirent ); - } - - if (UnlockFcb) { CdUnlockFcb( IrpContext, Fcb ); } - } - - return; -} - - -VOID -CdAddAllocationFromDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN ULONG McbEntryOffset, - IN LONGLONG StartingFileOffset, - IN PDIRENT Dirent - ) - -/*++ - -Routine Description: - - This routine is called to add an entry into the Cd Mcb. We grow the Mcb - as necessary and update the new entry. - - NOTE - The Fcb has already been locked prior to makeing this call. - -Arguments: - - Fcb - Fcb containing the Mcb to update. - - McbEntryOffset - Offset into the Mcb array to add this data. - - StartingFileOffset - Offset in bytes from the start of the file. - - Dirent - Dirent containing the on-disk data for this entry. - -Return Value: - - None - ---*/ - -{ - ULONG NewArraySize; - PVOID NewMcbArray; - PCD_MCB_ENTRY McbEntry; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - ASSERT_LOCKED_FCB( Fcb ); - - // - // If we need to grow the Mcb then do it now. - // - - if (McbEntryOffset >= Fcb->Mcb.MaximumEntryCount) { - - // - // Allocate a new buffer and copy the old data over. - // - - NewArraySize = Fcb->Mcb.MaximumEntryCount * 2 * sizeof( CD_MCB_ENTRY ); - - NewMcbArray = FsRtlAllocatePoolWithTag( CdPagedPool, - NewArraySize, - TAG_MCB_ARRAY ); - - RtlZeroMemory( NewMcbArray, NewArraySize ); - RtlCopyMemory( NewMcbArray, - Fcb->Mcb.McbArray, - Fcb->Mcb.MaximumEntryCount * sizeof( CD_MCB_ENTRY )); - - // - // Deallocate the current array unless it is embedded in the Fcb. - // - - if (Fcb->Mcb.MaximumEntryCount != 1) { - - CdFreePool( &Fcb->Mcb.McbArray ); - } - - // - // Now update the Mcb with the new array. - // - - Fcb->Mcb.MaximumEntryCount *= 2; - Fcb->Mcb.McbArray = NewMcbArray; - } - - // - // Update the new entry with the input data. - // - - McbEntry = Fcb->Mcb.McbArray + McbEntryOffset; - - // - // Start with the location and length on disk. - // - - McbEntry->DiskOffset = LlBytesFromBlocks( Fcb->Vcb, Dirent->StartingOffset ); - McbEntry->ByteCount = Dirent->DataLength; - - // - // Round the byte count up to a logical block boundary if this is - // the last extent. - // - - if (!FlagOn( Dirent->DirentFlags, CD_ATTRIBUTE_MULTI )) { - - McbEntry->ByteCount = BlockAlign( Fcb->Vcb, McbEntry->ByteCount ); - } - - // - // The file offset is the logical position within this file. - // We know this is correct regardless of whether we bias the - // file size or disk offset. - // - - McbEntry->FileOffset = StartingFileOffset; - - // - // Convert the interleave information from logical blocks to - // bytes. - // - - if (Dirent->FileUnitSize != 0) { - - McbEntry->DataBlockByteCount = LlBytesFromBlocks( Fcb->Vcb, Dirent->FileUnitSize ); - McbEntry->TotalBlockByteCount = McbEntry->DataBlockByteCount + - LlBytesFromBlocks( Fcb->Vcb, Dirent->InterleaveGapSize ); - - // - // If the file is not interleaved then the size of the data block - // and total block are the same as the byte count. - // - - } else { - - McbEntry->DataBlockByteCount = - McbEntry->TotalBlockByteCount = McbEntry->ByteCount; - } - - // - // Update the number of entries in the Mcb. The Mcb is never sparse - // so whenever we add an entry it becomes the last entry in the Mcb. - // - - Fcb->Mcb.CurrentEntryCount = McbEntryOffset + 1; - - return; -} - - -VOID -CdAddInitialAllocation ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN ULONG StartingBlock, - IN LONGLONG DataLength - ) - -/*++ - -Routine Description: - - This routine is called to set up the initial entry in an Mcb. - - This routine handles the single initial entry for a directory file. We will - round the start block down to a sector boundary. Our caller has already - biased the DataLength with any adjustments. This is used for the case - where there is a single entry and we want to align the data on a sector - boundary. - -Arguments: - - Fcb - Fcb containing the Mcb to update. - - StartingBlock - Starting logical block for this directory. This is - the start of the actual data. We will bias this by the sector - offset of the data. - - DataLength - Length of the data. - -Return Value: - - None - ---*/ - -{ - PCD_MCB_ENTRY McbEntry; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - ASSERT_LOCKED_FCB( Fcb ); - ASSERT( 0 == Fcb->Mcb.CurrentEntryCount); - ASSERT( CDFS_NTC_FCB_DATA != Fcb->NodeTypeCode); - - // - // Update the new entry with the input data. - // - - McbEntry = Fcb->Mcb.McbArray; - - // - // Start with the location and length on disk. - // - - McbEntry->DiskOffset = LlBytesFromBlocks( Fcb->Vcb, StartingBlock ); - McbEntry->DiskOffset -= Fcb->StreamOffset; - - McbEntry->ByteCount = DataLength; - - // - // The file offset is the logical position within this file. - // We know this is correct regardless of whether we bias the - // file size or disk offset. - // - - McbEntry->FileOffset = 0; - - // - // If the file is not interleaved then the size of the data block - // and total block are the same as the byte count. - // - - McbEntry->DataBlockByteCount = - McbEntry->TotalBlockByteCount = McbEntry->ByteCount; - - // - // Update the number of entries in the Mcb. The Mcb is never sparse - // so whenever we add an entry it becomes the last entry in the Mcb. - // - - Fcb->Mcb.CurrentEntryCount = 1; - - return; -} - - -VOID -CdTruncateAllocation ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG StartingFileOffset - ) - -/*++ - -Routine Description: - - This routine truncates the Mcb for a file by eliminating all of the Mcb - entries from the entry which contains the given offset. - - The Fcb should be locked when this routine is called. - -Arguments: - - Fcb - Fcb containing the Mcb to truncate. - - StartingFileOffset - Offset in the file to truncate the Mcb from. - -Return Value: - - None - ---*/ - -{ - ULONG McbEntryOffset; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - ASSERT_LOCKED_FCB( Fcb ); - - // - // Find the entry containg this starting offset. - // - - McbEntryOffset = CdFindMcbEntry( IrpContext, Fcb, StartingFileOffset ); - - // - // Now set the current size of the mcb to this point. - // - - Fcb->Mcb.CurrentEntryCount = McbEntryOffset; - - return; -} - - -VOID -CdInitializeMcb ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb - ) - -/*++ - -Routine Description: - - This routine is called to initialize the Mcb in an Fcb. We initialize - this with an entry count of one and point to the entry in the Fcb - itself. - - Fcb should be acquired exclusively when this is called. - -Arguments: - - Fcb - Fcb containing the Mcb to initialize. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - - // - // Set the entry counts to show there is one entry in the array and - // it is unused. - // - - Fcb->Mcb.MaximumEntryCount = 1; - Fcb->Mcb.CurrentEntryCount = 0; - - Fcb->Mcb.McbArray = &Fcb->McbEntry; - - return; -} - - -VOID -CdUninitializeMcb ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb - ) - -/*++ - -Routine Description: - - This routine is called to cleanup an Mcb in an Fcb. We look at the - maximum run count in the Fcb and if greater than one we will deallocate - the buffer. - - Fcb should be acquired exclusively when this is called. - -Arguments: - - Fcb - Fcb containing the Mcb to uninitialize. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - - // - // If the count is greater than one then this is an allocated buffer. - // - - if (Fcb->Mcb.MaximumEntryCount > 1) { - - CdFreePool( &Fcb->Mcb.McbArray ); - } - - return; -} - - -// -// Local suupport routine -// - -ULONG -CdFindMcbEntry ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG FileOffset - ) - -/*++ - -Routine Description: - - This routine is called to find the Mcb entry which contains the file - offset at the given point. If the file offset is not currently in the - Mcb then we return the offset of the entry to add. - - Fcb should be locked when this is called. - -Arguments: - - Fcb - Fcb containing the Mcb to uninitialize. - - FileOffset - Return the Mcb entry which contains this file offset. - -Return Value: - - ULONG - Offset in the Mcb of the entry for this offset. - ---*/ - -{ - ULONG CurrentMcbOffset; - PCD_MCB_ENTRY CurrentMcbEntry; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - ASSERT_LOCKED_FCB( Fcb ); - - // - // We expect a linear search will be sufficient here. - // - - CurrentMcbOffset = 0; - CurrentMcbEntry = Fcb->Mcb.McbArray; - - while (CurrentMcbOffset < Fcb->Mcb.CurrentEntryCount) { - - // - // Check if the offset lies within the current Mcb position. - // - - if (FileOffset < CurrentMcbEntry->FileOffset + CurrentMcbEntry->ByteCount) { - - break; - } - - // - // Move to the next entry. - // - - CurrentMcbOffset += 1; - CurrentMcbEntry += 1; - } - - // - // This is the offset containing this file offset (or the point - // where an entry should be added). - // - - return CurrentMcbOffset; -} - - -// -// Local support routine -// - -VOID -CdDiskOffsetFromMcbEntry ( - IN PIRP_CONTEXT IrpContext, - IN PCD_MCB_ENTRY McbEntry, - IN LONGLONG FileOffset, - IN PLONGLONG DiskOffset, - IN PULONG ByteCount - ) - -/*++ - -Routine Description: - - This routine is called to return the diskoffset and length of the file - data which begins at offset 'FileOffset'. We have the Mcb entry which - contains the mapping and interleave information. - - NOTE - This routine deals with data in 2048 byte logical sectors. If - this is an XA file then our caller has already converted from - 'raw' file bytes to 'cooked' file bytes. - -Arguments: - - McbEntry - Entry in the Mcb containing the allocation information. - - FileOffset - Starting Offset in the file to find the matching disk - offsets. - - DiskOffset - Address to store the starting disk offset for this operation. - - ByteCount - Address to store number of contiguous bytes starting at this - disk offset. - -Return Value: - - None - ---*/ - -{ - LONGLONG ExtentOffset; - - LONGLONG CurrentDiskOffset; - LONGLONG CurrentExtentOffset; - - LONGLONG LocalByteCount; - - PAGED_CODE(); - ASSERT_IRP_CONTEXT( IrpContext ); - - // - // Extent offset is the difference between the file offset and the start - // of the extent. - // - - ExtentOffset = FileOffset - McbEntry->FileOffset; - - // - // Optimize the non-interleave case. - // - - if (McbEntry->ByteCount == McbEntry->DataBlockByteCount) { - - *DiskOffset = McbEntry->DiskOffset + ExtentOffset; - - LocalByteCount = McbEntry->ByteCount - ExtentOffset; - - } else { - - // - // Walk though any interleave until we reach the current offset in - // this extent. - // - - CurrentExtentOffset = McbEntry->DataBlockByteCount; - CurrentDiskOffset = McbEntry->DiskOffset; - - while (CurrentExtentOffset <= ExtentOffset) { - - CurrentDiskOffset += McbEntry->TotalBlockByteCount; - CurrentExtentOffset += McbEntry->DataBlockByteCount; - } - - // - // We are now positioned at the data block containing the starting - // file offset we were given. The disk offset is the offset of - // the start of this block plus the extent offset into this block. - // The byte count is the data block byte count minus our offset into - // this block. - // - - *DiskOffset = CurrentDiskOffset + (ExtentOffset + McbEntry->DataBlockByteCount - CurrentExtentOffset); - - // - // Make sure we aren't past the end of the data length. This is possible - // if we only use part of the last data block on an interleaved file. - // - - if (CurrentExtentOffset > McbEntry->ByteCount) { - - CurrentExtentOffset = McbEntry->ByteCount; - } - - LocalByteCount = CurrentExtentOffset - ExtentOffset; - } - - // - // If the byte count exceeds our limit then cut it to fit in 32 bits. - // - - if (LocalByteCount > MAXULONG) { - - *ByteCount = MAXULONG; - - } else { - - *ByteCount = (ULONG) LocalByteCount; - } - - return; -} - diff --git a/reactos/drivers/filesystems/cdfs_new/cachesup.c b/reactos/drivers/filesystems/cdfs_new/cachesup.c deleted file mode 100755 index b31422f97e0..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/cachesup.c +++ /dev/null @@ -1,644 +0,0 @@ -/*++ - -Copyright (c) 1990-2000 Microsoft Corporation - -Module Name: - - Cache.c - -Abstract: - - This module implements the cache management routines for the Cdfs - FSD and FSP, by calling the Common Cache Manager. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_CACHESUP) - -// -// Local debug trace level -// - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCompleteMdl) -#pragma alloc_text(PAGE, CdCreateInternalStream) -#pragma alloc_text(PAGE, CdDeleteInternalStream) -#pragma alloc_text(PAGE, CdPurgeVolume) -#endif - - -VOID -CdCreateInternalStream ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFCB Fcb - ) - -/*++ - -Routine Description: - - This function creates an internal stream file for interaction - with the cache manager. The Fcb here can be for either a - directory stream or for a path table stream. - -Arguments: - - Vcb - Vcb for this volume. - - Fcb - Points to the Fcb for this file. It is either an Index or - Path Table Fcb. - -Return Value: - - None. - ---*/ - -{ - PFILE_OBJECT StreamFile = NULL; - BOOLEAN DecrementReference = FALSE; - - BOOLEAN CleanupDirContext = FALSE; - BOOLEAN UpdateFcbSizes = FALSE; - - DIRENT Dirent; - DIRENT_ENUM_CONTEXT DirContext; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - - // - // We may only have the Fcb shared. Lock the Fcb and do a - // safe test to see if we need to really create the file object. - // - - CdLockFcb( IrpContext, Fcb ); - - if (Fcb->FileObject != NULL) { - - CdUnlockFcb( IrpContext, Fcb ); - return; - } - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Create the internal stream. The Vpb should be pointing at our volume - // device object at this point. - // - - StreamFile = IoCreateStreamFileObject( NULL, Vcb->Vpb->RealDevice ); - - if (StreamFile == NULL) { - - CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); - } - - // - // Initialize the fields of the file object. - // - - StreamFile->ReadAccess = TRUE; - StreamFile->WriteAccess = FALSE; - StreamFile->DeleteAccess = FALSE; - - StreamFile->SectionObjectPointer = &Fcb->FcbNonpaged->SegmentObject; - - // - // Set the file object type and increment the Vcb counts. - // - - CdSetFileObject( IrpContext, - StreamFile, - StreamFileOpen, - Fcb, - NULL ); - - // - // We will reference the current Fcb twice to keep it from going - // away in the error path. Otherwise if we dereference it - // below in the finally clause a close could cause the Fcb to - // be deallocated. - // - - CdLockVcb( IrpContext, Vcb ); - CdIncrementReferenceCounts( IrpContext, Fcb, 2, 0 ); - CdUnlockVcb( IrpContext, Vcb ); - DecrementReference = TRUE; - - // - // Initialize the cache map for the file. - // - - CcInitializeCacheMap( StreamFile, - (PCC_FILE_SIZES)&Fcb->AllocationSize, - TRUE, - &CdData.CacheManagerCallbacks, - Fcb ); - - // - // Go ahead and store the stream file into the Fcb. - // - - Fcb->FileObject = StreamFile; - StreamFile = NULL; - - // - // If this is the first file object for a directory then we need to - // read the self entry for this directory and update the sizes - // in the Fcb. We know that the Fcb has been initialized so - // that we have a least one sector available to read. - // - - if (!FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED )) { - - ULONG NewDataLength; - - // - // Initialize the search structures. - // - - CdInitializeDirContext( IrpContext, &DirContext ); - CdInitializeDirent( IrpContext, &Dirent ); - CleanupDirContext = TRUE; - - // - // Read the dirent from disk and transfer the data to the - // in-memory dirent. - // - - CdLookupDirent( IrpContext, - Fcb, - Fcb->StreamOffset, - &DirContext ); - - CdUpdateDirentFromRawDirent( IrpContext, Fcb, &DirContext, &Dirent ); - - // - // Verify that this really for the self entry. We do this by - // updating the name in the dirent and then checking that it matches - // one of the hard coded names. - // - - CdUpdateDirentName( IrpContext, &Dirent, FALSE ); - - if (Dirent.CdFileName.FileName.Buffer != CdUnicodeSelfArray) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - // - // If the data sizes are different then update the header - // and Mcb for this Fcb. - // - - NewDataLength = BlockAlign( Vcb, Dirent.DataLength + Fcb->StreamOffset ); - - if (NewDataLength == 0) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - if (NewDataLength != Fcb->FileSize.QuadPart) { - - Fcb->AllocationSize.QuadPart = - Fcb->FileSize.QuadPart = - Fcb->ValidDataLength.QuadPart = NewDataLength; - - CcSetFileSizes( Fcb->FileObject, (PCC_FILE_SIZES) &Fcb->AllocationSize ); - - CdTruncateAllocation( IrpContext, Fcb, 0 ); - CdAddInitialAllocation( IrpContext, - Fcb, - Dirent.StartingOffset, - NewDataLength ); - - UpdateFcbSizes = TRUE; - } - - // - // Check for the existence flag and transform to hidden. - // - - if (FlagOn( Dirent.DirentFlags, CD_ATTRIBUTE_HIDDEN )) { - - SetFlag( Fcb->FileAttributes, FILE_ATTRIBUTE_HIDDEN ); - } - - // - // Convert the time to NT time. - // - - CdConvertCdTimeToNtTime( IrpContext, - Dirent.CdTime, - (PLARGE_INTEGER) &Fcb->CreationTime ); - - // - // Update the Fcb flags to indicate we have read the - // self entry. - // - - SetFlag( Fcb->FcbState, FCB_STATE_INITIALIZED ); - - // - // If we updated the sizes then we want to purge the file. Go - // ahead and unpin and then purge the first page. - // - - CdCleanupDirContext( IrpContext, &DirContext ); - CdCleanupDirent( IrpContext, &Dirent ); - CleanupDirContext = FALSE; - - if (UpdateFcbSizes) { - - CcPurgeCacheSection( &Fcb->FcbNonpaged->SegmentObject, - NULL, - 0, - FALSE ); - } - } - - } finally { - - // - // Cleanup any dirent structures we may have used. - // - - if (CleanupDirContext) { - - CdCleanupDirContext( IrpContext, &DirContext ); - CdCleanupDirent( IrpContext, &Dirent ); - } - - // - // If we raised then we need to dereference the file object. - // - - if (StreamFile != NULL) { - - ObDereferenceObject( StreamFile ); - Fcb->FileObject = NULL; - } - - // - // Dereference and unlock the Fcb. - // - - if (DecrementReference) { - - CdLockVcb( IrpContext, Vcb ); - CdDecrementReferenceCounts( IrpContext, Fcb, 1, 0 ); - CdUnlockVcb( IrpContext, Vcb ); - } - - CdUnlockFcb( IrpContext, Fcb ); - } - - return; -} - - -VOID -CdDeleteInternalStream ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb - ) - -/*++ - -Routine Description: - - This function creates an internal stream file for interaction - with the cache manager. The Fcb here can be for either a - directory stream or for a path table stream. - -Arguments: - - Fcb - Points to the Fcb for this file. It is either an Index or - Path Table Fcb. - -Return Value: - - None. - ---*/ - -{ - PFILE_OBJECT FileObject; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - - // - // Lock the Fcb. - // - - CdLockFcb( IrpContext, Fcb ); - - // - // Capture the file object. - // - - FileObject = Fcb->FileObject; - Fcb->FileObject = NULL; - - // - // It is now safe to unlock the Fcb. - // - - CdUnlockFcb( IrpContext, Fcb ); - - // - // Dereference the file object if present. - // - - if (FileObject != NULL) { - - if (FileObject->PrivateCacheMap != NULL) { - - CcUninitializeCacheMap( FileObject, NULL, NULL ); - } - - ObDereferenceObject( FileObject ); - } - - return; -} - - -NTSTATUS -CdCompleteMdl ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine performs the function of completing Mdl reads. - It should be called only from CdFsdRead. - -Arguments: - - Irp - Supplies the originating Irp. - -Return Value: - - NTSTATUS - Will always be STATUS_SUCCESS. - ---*/ - -{ - PFILE_OBJECT FileObject; - - PAGED_CODE(); - - // - // Do completion processing. - // - - FileObject = IoGetCurrentIrpStackLocation( Irp )->FileObject; - - CcMdlReadComplete( FileObject, Irp->MdlAddress ); - - // - // Mdl is now deallocated. - // - - Irp->MdlAddress = NULL; - - // - // Complete the request and exit right away. - // - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - - return STATUS_SUCCESS; -} - - -NTSTATUS -CdPurgeVolume ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN BOOLEAN DismountUnderway - ) - -/*++ - -Routine Description: - - This routine is called to purge the volume. The purpose is to make all the stale file - objects in the system go away in order to lock the volume. - - The Vcb is already acquired exclusively. We will lock out all file operations by - acquiring the global file resource. Then we will walk through all of the Fcb's and - perform the purge. - -Arguments: - - Vcb - Vcb for the volume to purge. - - DismountUnderway - Indicates that we are trying to delete all of the objects. - We will purge the Path Table and VolumeDasd and dereference all - internal streams. - -Return Value: - - NTSTATUS - The first failure of the purge operation. - ---*/ - -{ - NTSTATUS Status = STATUS_SUCCESS; - - PVOID RestartKey = NULL; - PFCB ThisFcb = NULL; - PFCB NextFcb; - - BOOLEAN RemovedFcb; - - PAGED_CODE(); - - ASSERT_EXCLUSIVE_VCB( Vcb); - - // - // Force any remaining Fcb's in the delayed close queue to be closed. - // - - CdFspClose( Vcb ); - - // - // Acquire the global file resource. - // - - CdAcquireAllFiles( IrpContext, Vcb ); - - // - // Loop through each Fcb in the Fcb Table and perform the flush. - // - - while (TRUE) { - - // - // Lock the Vcb to lookup the next Fcb. - // - - CdLockVcb( IrpContext, Vcb ); - NextFcb = CdGetNextFcb( IrpContext, Vcb, &RestartKey ); - - // - // Reference the NextFcb if present. - // - - if (NextFcb != NULL) { - - NextFcb->FcbReference += 1; - } - - // - // If the last Fcb is present then decrement reference count and call teardown - // to see if it should be removed. - // - - if (ThisFcb != NULL) { - - ThisFcb->FcbReference -= 1; - - CdUnlockVcb( IrpContext, Vcb ); - - CdTeardownStructures( IrpContext, ThisFcb, &RemovedFcb ); - - } else { - - CdUnlockVcb( IrpContext, Vcb ); - } - - // - // Break out of the loop if no more Fcb's. - // - - if (NextFcb == NULL) { - - break; - } - - // - // Move to the next Fcb. - // - - ThisFcb = NextFcb; - - // - // If there is a image section then see if that can be closed. - // - - if (ThisFcb->FcbNonpaged->SegmentObject.ImageSectionObject != NULL) { - - MmFlushImageSection( &ThisFcb->FcbNonpaged->SegmentObject, MmFlushForWrite ); - } - - // - // If there is a data section then purge this. If there is an image - // section then we won't be able to. Remember this if it is our first - // error. - // - - if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) && - !CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject, - NULL, - 0, - FALSE ) && - (Status == STATUS_SUCCESS)) { - - Status = STATUS_UNABLE_TO_DELETE_SECTION; - } - - // - // Dereference the internal stream if dismounting. - // - - if (DismountUnderway && - (SafeNodeType( ThisFcb ) != CDFS_NTC_FCB_DATA) && - (ThisFcb->FileObject != NULL)) { - - CdDeleteInternalStream( IrpContext, ThisFcb ); - } - } - - // - // Now look at the path table and volume Dasd Fcb's. - // - - if (DismountUnderway) { - - if (Vcb->PathTableFcb != NULL) { - - ThisFcb = Vcb->PathTableFcb; - InterlockedIncrement( &Vcb->PathTableFcb->FcbReference ); - - if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) && - !CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject, - NULL, - 0, - FALSE ) && - (Status == STATUS_SUCCESS)) { - - Status = STATUS_UNABLE_TO_DELETE_SECTION; - } - - CdDeleteInternalStream( IrpContext, ThisFcb ); - - InterlockedDecrement( &ThisFcb->FcbReference ); - - CdTeardownStructures( IrpContext, ThisFcb, &RemovedFcb ); - } - - if (Vcb->VolumeDasdFcb != NULL) { - - ThisFcb = Vcb->VolumeDasdFcb; - InterlockedIncrement( &ThisFcb->FcbReference ); - - if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) && - !CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject, - NULL, - 0, - FALSE ) && - (Status == STATUS_SUCCESS)) { - - Status = STATUS_UNABLE_TO_DELETE_SECTION; - } - - InterlockedDecrement( &ThisFcb->FcbReference ); - - CdTeardownStructures( IrpContext, ThisFcb, &RemovedFcb ); - } - } - - // - // Release all of the files. - // - - CdReleaseAllFiles( IrpContext, Vcb ); - - return Status; -} - - diff --git a/reactos/drivers/filesystems/cdfs_new/cd.h b/reactos/drivers/filesystems/cdfs_new/cd.h deleted file mode 100755 index 69dc11d5227..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/cd.h +++ /dev/null @@ -1,534 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - Cd.h - -Abstract: - - This module defines the on-disk structure of the Cdfs file system. - - ---*/ - -#ifndef _CDFS_ -#define _CDFS_ - -// -// Sector size on Cdrom disks is hard-coded to 2048 -// - -#ifndef SECTOR_SIZE -#define SECTOR_SIZE (2048) -#endif - -#define RAW_SECTOR_SIZE (2352) -#define SECTOR_MASK (SECTOR_SIZE - 1) -#define INVERSE_SECTOR_MASK ~(SECTOR_SIZE - 1) - -#ifndef SECTOR_SHIFT -#define SECTOR_SHIFT (11) -#endif - -#define XA_SECTOR_SIZE (2352) - -// -// Cdfs file id is a large integer. -// - -typedef LARGE_INTEGER FILE_ID; -typedef FILE_ID *PFILE_ID; - -// -// The following constants are values from the disk. -// - -#define FIRST_VD_SECTOR (16) - -#define VOL_ID_LEN (5) -#define ESC_SEQ_LEN (3) - -#define VERSION_1 (1) - -#define VD_TERMINATOR (255) -#define VD_PRIMARY (1) -#define VD_SECONDARY (2) - -#define VOLUME_ID_LENGTH (32) - -// -// Leave the following so that CdfsBoot.c will compile -// - -#define CD_SECTOR_SIZE (2048) - -#define ISO_VOL_ID "CD001" -#define HSG_VOL_ID "CDROM" - -#define ISO_ATTR_MULTI 0x0080 -#define ISO_ATTR_DIRECTORY 0x0002 - -#define MIN_DIR_REC_SIZE (sizeof( RAW_DIR_REC ) - MAX_FILE_ID_LENGTH) - -#define RVD_STD_ID( r, i ) (i ? r->StandardId : \ - ((PRAW_HSG_VD) r)->StandardId ) - -#define RVD_DESC_TYPE( r, i ) (i ? r->DescType : \ - ((PRAW_HSG_VD) r)->DescType ) - -#define RVD_VERSION( r, i ) (i ? r->Version : \ - ((PRAW_HSG_VD) r)->Version ) - -#define RVD_LB_SIZE( r, i ) (i ? r->LogicalBlkSzI : \ - ((PRAW_HSG_VD) r)->LogicalBlkSzI ) - -#define RVD_VOL_SIZE( r, i ) (i ? r->VolSpaceI : \ - ((PRAW_HSG_VD) r)->VolSpaceI ) - -#define RVD_ROOT_DE( r, i ) (i ? r->RootDe : \ - ((PRAW_HSG_VD) r)->RootDe ) - -#define DE_FILE_FLAGS( iso, de ) (iso ? de->FlagsISO : de->FlagsHSG) - -// -// Data track flag for track entries in TOC -// - -#define TOC_DATA_TRACK (0x04) -#define TOC_LAST_TRACK (0xaa) - - -// -// There is considerable rearrangement of the volume descriptors for -// ISO and HSG. However, within each standard the same structure can -// be used for both the primary and secondary descriptors. -// -// Both of these structures are aligned correctly so that no -// special macros will be needed to unpack them. -// - -// -// Declaration of length of root directory entry in volume descriptor -// - -#define LEN_ROOT_DE (34) - -// -// Maximum length of file ID on the disk. We allow file size beyond the ISO 9660 -// standard. -// - -#define MAX_FILE_ID_LENGTH (255) - - -typedef struct _RAW_ISO_VD { - - UCHAR DescType; // volume type: 1 = standard, 2 = coded - UCHAR StandardId[5]; // volume structure standard id = CD001 - UCHAR Version; // volume structure version number = 1 - UCHAR VolumeFlags; // volume flags - UCHAR SystemId[32]; // system identifier - UCHAR VolumeId[32]; // volume identifier - UCHAR Reserved[8]; // reserved 8 = 0 - ULONG VolSpaceI; // size of the volume in LBN's Intel - ULONG VolSpaceM; // size of the volume in LBN's Motorola - UCHAR CharSet[32]; // character set bytes 0 = ASCII - USHORT VolSetSizeI; // volume set size Intel - USHORT VolSetSizeM; // volume set size Motorola - USHORT VolSeqNumI; // volume set sequence number Intel - USHORT VolSeqNumM; // volume set sequence number Motorola - USHORT LogicalBlkSzI; // logical block size Intel - USHORT LogicalBlkSzM; // logical block size Motorola - ULONG PathTableSzI; // path table size in bytes Intel - ULONG PathTableSzM; // path table size in bytes Motorola - ULONG PathTabLocI[2]; // LBN of 2 path tables Intel - ULONG PathTabLocM[2]; // LBN of 2 path tables Motorola - UCHAR RootDe[LEN_ROOT_DE];// dir entry of the root directory - UCHAR VolSetId[128]; // volume set identifier - UCHAR PublId[128]; // publisher identifier - UCHAR PreparerId[128]; // data preparer identifier - UCHAR AppId[128]; // application identifier - UCHAR Copyright[37]; // file name of copyright notice - UCHAR Abstract[37]; // file name of abstract - UCHAR Bibliograph[37]; // file name of bibliography - UCHAR CreateDate[17]; // volume creation date and time - UCHAR ModDate[17]; // volume modification date and time - UCHAR ExpireDate[17]; // volume expiration date and time - UCHAR EffectDate[17]; // volume effective date and time - UCHAR FileStructVer; // file structure version number = 1 - UCHAR Reserved3; // reserved - UCHAR ResApp[512]; // reserved for application - UCHAR Reserved4[653]; // remainder of 2048 bytes reserved - -} RAW_ISO_VD; -typedef RAW_ISO_VD *PRAW_ISO_VD; - - -typedef struct _RAW_HSG_VD { - - ULONG BlkNumI; // logical block number Intel - ULONG BlkNumM; // logical block number Motorola - UCHAR DescType; // volume type: 1 = standard, 2 = coded - UCHAR StandardId[5]; // volume structure standard id = CDROM - UCHAR Version; // volume structure version number = 1 - UCHAR VolumeFlags; // volume flags - UCHAR SystemId[32]; // system identifier - UCHAR VolumeId[32]; // volume identifier - UCHAR Reserved[8]; // reserved 8 = 0 - ULONG VolSpaceI; // size of the volume in LBN's Intel - ULONG VolSpaceM; // size of the volume in LBN's Motorola - UCHAR CharSet[32]; // character set bytes 0 = ASCII - USHORT VolSetSizeI; // volume set size Intel - USHORT VolSetSizeM; // volume set size Motorola - USHORT VolSeqNumI; // volume set sequence number Intel - USHORT VolSeqNumM; // volume set sequence number Motorola - USHORT LogicalBlkSzI; // logical block size Intel - USHORT LogicalBlkSzM; // logical block size Motorola - ULONG PathTableSzI; // path table size in bytes Intel - ULONG PathTableSzM; // path table size in bytes Motorola - ULONG PathTabLocI[4]; // LBN of 4 path tables Intel - ULONG PathTabLocM[4]; // LBN of 4 path tables Motorola - UCHAR RootDe[LEN_ROOT_DE];// dir entry of the root directory - UCHAR VolSetId[128]; // volume set identifier - UCHAR PublId[128]; // publisher identifier - UCHAR PreparerId[128]; // data preparer identifier - UCHAR AppId[128]; // application identifier - UCHAR Copyright[32]; // file name of copyright notice - UCHAR Abstract[32]; // file name of abstract - UCHAR CreateDate[16]; // volume creation date and time - UCHAR ModDate[16]; // volume modification date and time - UCHAR ExpireDate[16]; // volume expiration date and time - UCHAR EffectDate[16]; // volume effective date and time - UCHAR FileStructVer; // file structure version number - UCHAR Reserved3; // reserved - UCHAR ResApp[512]; // reserved for application - UCHAR Reserved4[680]; // remainder of 2048 bytes reserved - -} RAW_HSG_VD; -typedef RAW_HSG_VD *PRAW_HSG_VD; - - -typedef struct _RAW_JOLIET_VD { - - UCHAR DescType; // volume type: 2 = coded - UCHAR StandardId[5]; // volume structure standard id = CD001 - UCHAR Version; // volume structure version number = 1 - UCHAR VolumeFlags; // volume flags - UCHAR SystemId[32]; // system identifier - UCHAR VolumeId[32]; // volume identifier - UCHAR Reserved[8]; // reserved 8 = 0 - ULONG VolSpaceI; // size of the volume in LBN's Intel - ULONG VolSpaceM; // size of the volume in LBN's Motorola - UCHAR CharSet[32]; // character set bytes 0 = ASCII, Joliett Seq here - USHORT VolSetSizeI; // volume set size Intel - USHORT VolSetSizeM; // volume set size Motorola - USHORT VolSeqNumI; // volume set sequence number Intel - USHORT VolSeqNumM; // volume set sequence number Motorola - USHORT LogicalBlkSzI; // logical block size Intel - USHORT LogicalBlkSzM; // logical block size Motorola - ULONG PathTableSzI; // path table size in bytes Intel - ULONG PathTableSzM; // path table size in bytes Motorola - ULONG PathTabLocI[2]; // LBN of 2 path tables Intel - ULONG PathTabLocM[2]; // LBN of 2 path tables Motorola - UCHAR RootDe[LEN_ROOT_DE];// dir entry of the root directory - UCHAR VolSetId[128]; // volume set identifier - UCHAR PublId[128]; // publisher identifier - UCHAR PreparerId[128]; // data preparer identifier - UCHAR AppId[128]; // application identifier - UCHAR Copyright[37]; // file name of copyright notice - UCHAR Abstract[37]; // file name of abstract - UCHAR Bibliograph[37]; // file name of bibliography - UCHAR CreateDate[17]; // volume creation date and time - UCHAR ModDate[17]; // volume modification date and time - UCHAR ExpireDate[17]; // volume expiration date and time - UCHAR EffectDate[17]; // volume effective date and time - UCHAR FileStructVer; // file structure version number = 1 - UCHAR Reserved3; // reserved - UCHAR ResApp[512]; // reserved for application - UCHAR Reserved4[653]; // remainder of 2048 bytes reserved - -} RAW_JOLIET_VD; -typedef RAW_JOLIET_VD *PRAW_JOLIET_VD; - -// -// Macros to access the different volume descriptors. -// - -#define CdRvdId(R,F) ( \ - FlagOn( (F), VCB_STATE_HSG ) ? \ - ((PRAW_HSG_VD) (R))->StandardId : \ - ((PRAW_ISO_VD) (R))->StandardId \ -) - -#define CdRvdVersion(R,F) ( \ - FlagOn( (F), VCB_STATE_HSG ) ? \ - ((PRAW_HSG_VD) (R))->Version : \ - ((PRAW_ISO_VD) (R))->Version \ -) - -#define CdRvdDescType(R,F) ( \ - FlagOn( (F), VCB_STATE_HSG ) ? \ - ((PRAW_HSG_VD) (R))->DescType : \ - ((PRAW_ISO_VD) (R))->DescType \ -) - -#define CdRvdEsc(R,F) ( \ - FlagOn( (F), VCB_STATE_HSG ) ? \ - ((PRAW_HSG_VD) (R))->CharSet : \ - ((PRAW_ISO_VD) (R))->CharSet \ -) - -#define CdRvdVolId(R,F) ( \ - FlagOn( (F), VCB_STATE_HSG ) ? \ - ((PRAW_HSG_VD) (R))->VolumeId : \ - ((PRAW_ISO_VD) (R))->VolumeId \ -) - -#define CdRvdBlkSz(R,F) ( \ - FlagOn( (F), VCB_STATE_HSG ) ? \ - ((PRAW_HSG_VD) (R))->LogicalBlkSzI :\ - ((PRAW_ISO_VD) (R))->LogicalBlkSzI \ -) - -#define CdRvdPtLoc(R,F) ( \ - FlagOn( (F), VCB_STATE_HSG ) ? \ - ((PRAW_HSG_VD) (R))->PathTabLocI[0]:\ - ((PRAW_ISO_VD) (R))->PathTabLocI[0] \ -) - -#define CdRvdPtSz(R,F) ( \ - FlagOn( (F), VCB_STATE_HSG ) ? \ - ((PRAW_HSG_VD) (R))->PathTableSzI : \ - ((PRAW_ISO_VD) (R))->PathTableSzI \ -) - -#define CdRvdDirent(R,F) ( \ - FlagOn( (F), VCB_STATE_HSG ) ? \ - ((PRAW_HSG_VD) (R))->RootDe : \ - ((PRAW_ISO_VD) (R))->RootDe \ -) - -#define CdRvdVolSz(R,F) ( \ - FlagOn( (F), VCB_STATE_HSG ) ? \ - ((PRAW_HSG_VD) (R))->VolSpaceI : \ - ((PRAW_ISO_VD) (R))->VolSpaceI \ -) - - -// -// This structure is used to overlay a region of a disk sector -// to retrieve a single directory entry. There is a difference -// in the file flags between the ISO and HSG version and a -// additional byte in the ISO for the offset from Greenwich time. -// -// The disk structure is aligned on a word boundary, so any 32 -// bit fields will be represented as an array of 16 bit fields. -// - -typedef struct _RAW_DIRENT { - - UCHAR DirLen; - UCHAR XarLen; - UCHAR FileLoc[4]; - UCHAR FileLocMot[4]; - UCHAR DataLen[4]; - UCHAR DataLenMot[4]; - UCHAR RecordTime[6]; - UCHAR FlagsHSG; - UCHAR FlagsISO; - UCHAR IntLeaveSize; - UCHAR IntLeaveSkip; - UCHAR Vssn[2]; - UCHAR VssnMot[2]; - UCHAR FileIdLen; - UCHAR FileId[MAX_FILE_ID_LENGTH]; - -} RAW_DIRENT; -typedef RAW_DIRENT RAW_DIR_REC; -typedef RAW_DIRENT *PRAW_DIR_REC; -typedef RAW_DIRENT *PRAW_DIRENT; - -#define CD_ATTRIBUTE_HIDDEN (0x01) -#define CD_ATTRIBUTE_DIRECTORY (0x02) -#define CD_ATTRIBUTE_ASSOC (0x04) -#define CD_ATTRIBUTE_MULTI (0x80) - -#define CD_BASE_YEAR (1900) - -#define MIN_RAW_DIRENT_LEN (FIELD_OFFSET( RAW_DIRENT, FileId ) + 1) - -#define BYTE_COUNT_8_DOT_3 (24) - -#define SHORT_NAME_SHIFT (5) - -// -// The following macro recovers the correct flag field. -// - -#define CdRawDirentFlags(IC,RD) ( \ - FlagOn( (IC)->Vcb->VcbState, VCB_STATE_HSG) ? \ - (RD)->FlagsHSG : \ - (RD)->FlagsISO \ -) - -// -// The following macro converts from CD time to NT time. On ISO -// 9660 media, we now pay attention to the GMT offset (integer -// increments of 15 minutes offset from GMT). HSG does not record -// this field. -// -// The restriction to the interval [-48, 52] comes from 9660 8.4.26.1 -// -// VOID -// CdConvertCdTimeToNtTime ( -// IN PIRP_CONTEXT IrpContext, -// IN PCHAR CdTime, -// OUT PLARGE_INTEGER NtTime -// ); -// - -#define GMT_OFFSET_TO_NT ((LONGLONG) 15 * 60 * 1000 * 1000 * 10) - -#define CdConvertCdTimeToNtTime(IC,CD,NT) { \ - TIME_FIELDS _TimeField; \ - CHAR GmtOffset; \ - _TimeField.Year = (CSHORT) *((PCHAR) CD) + CD_BASE_YEAR; \ - _TimeField.Month = (CSHORT) *(Add2Ptr( CD, 1, PCHAR )); \ - _TimeField .Day = (CSHORT) *(Add2Ptr( CD, 2, PCHAR )); \ - _TimeField.Hour = (CSHORT) *(Add2Ptr( CD, 3, PCHAR )); \ - _TimeField.Minute = (CSHORT) *(Add2Ptr( CD, 4, PCHAR )); \ - _TimeField.Second = (CSHORT) *(Add2Ptr( CD, 5, PCHAR )); \ - _TimeField.Milliseconds = (CSHORT) 0; \ - RtlTimeFieldsToTime( &_TimeField, NT ); \ - if (!FlagOn((IC)->Vcb->VcbState, VCB_STATE_HSG) && \ - ((GmtOffset = *(Add2Ptr( CD, 6, PCHAR ))) != 0 ) && \ - (GmtOffset >= -48 && GmtOffset <= 52)) { \ - (NT)->QuadPart += -GmtOffset * GMT_OFFSET_TO_NT; \ - } \ -} - - -// -// The on-disk representation of a Path Table entry differs between -// the ISO version and the HSG version. The fields are the same -// and the same size, but the positions are different. -// - -typedef struct _RAW_PATH_ISO { - - UCHAR DirIdLen; - UCHAR XarLen; - USHORT DirLoc[2]; - USHORT ParentNum; - UCHAR DirId[MAX_FILE_ID_LENGTH]; - -} RAW_PATH_ISO; -typedef RAW_PATH_ISO *PRAW_PATH_ISO; -typedef RAW_PATH_ISO RAW_PATH_ENTRY; -typedef RAW_PATH_ISO *PRAW_PATH_ENTRY; - -typedef struct _RAW_PATH_HSG { - - USHORT DirLoc[2]; - UCHAR XarLen; - UCHAR DirIdLen; - USHORT ParentNum; - UCHAR DirId[MAX_FILE_ID_LENGTH]; - -} RAW_PATH_HSG; -typedef RAW_PATH_HSG *PRAW_PATH_HSG; - -#define MIN_RAW_PATH_ENTRY_LEN (FIELD_OFFSET( RAW_PATH_ENTRY, DirId ) + 1) - -// -// The following macros are used to recover the different fields of the -// Path Table entries. The macro to recover the disk location of the -// directory must copy it into a different variable for alignment reasons. -// -// CdRawPathIdLen - Length of directory name in bytes -// CdRawPathXar - Number of Xar blocks -// CdRawPathLoc - Address of unaligned ulong for disk offset in blocks -// - -#define CdRawPathIdLen(IC, RP) ( \ - FlagOn( (IC)->Vcb->VcbState, VCB_STATE_HSG ) ? \ - ((PRAW_PATH_HSG) (RP))->DirIdLen : \ - (RP)->DirIdLen \ -) - -#define CdRawPathXar(IC, RP) ( \ - FlagOn( (IC)->Vcb->VcbState, VCB_STATE_HSG ) ? \ - ((PRAW_PATH_HSG) (RP))->XarLen : \ - (RP)->XarLen \ -) - -#define CdRawPathLoc(IC, RP) ( \ - FlagOn( (IC)->Vcb->VcbState, VCB_STATE_HSG ) ? \ - ((PRAW_PATH_HSG) (RP))->DirLoc : \ - (RP)->DirLoc \ -) - - -// -// System use are for XA data. The following is the system use area for -// directory entries on XA data disks. -// - -typedef struct _SYSTEM_USE_XA { - - // - // Owner ID. Not used in this version. - // - - UCHAR OwnerId[4]; - - // - // Extent attributes. Only interested if mode2 form2 or digital audio. - // This is stored big endian. We will define the attribute flags so - // we can ignore this fact. - // - - USHORT Attributes; - - // - // XA signature. This value must be 'XA'. - // - - USHORT Signature; - - // - // File Number. - // - - UCHAR FileNumber; - - // - // Not used in this version. - // - - UCHAR Reserved[5]; - -} SYSTEM_USE_XA; -typedef SYSTEM_USE_XA *PSYSTEM_USE_XA; - -#define SYSTEM_USE_XA_FORM1 (0x0008) -#define SYSTEM_USE_XA_FORM2 (0x0010) -#define SYSTEM_USE_XA_DA (0x0040) - -#define SYSTEM_XA_SIGNATURE (0x4158) - -typedef enum _XA_EXTENT_TYPE { - - Form1Data = 0, - Mode2Form2Data, - CDAudio - -} XA_EXTENT_TYPE; -typedef XA_EXTENT_TYPE *PXA_EXTENT_TYPE; - -#endif // _CDFS_ - - - diff --git a/reactos/drivers/filesystems/cdfs_new/cddata.c b/reactos/drivers/filesystems/cdfs_new/cddata.c deleted file mode 100755 index db9d8940de6..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/cddata.c +++ /dev/null @@ -1,1150 +0,0 @@ - -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - CdData.c - -Abstract: - - This module declares the global data used by the Cdfs file system. - - This module also handles the dispath routines in the Fsd threads as well as - handling the IrpContext and Irp through the exception path. - - ---*/ - -#include "CdProcs.h" - -#ifdef CD_SANITY -BOOLEAN CdTestTopLevel = TRUE; -BOOLEAN CdTestRaisedStatus = TRUE; -BOOLEAN CdBreakOnAnyRaise = FALSE; -BOOLEAN CdTraceRaises = FALSE; -NTSTATUS CdInterestingExceptionCodes[] = { STATUS_DISK_CORRUPT_ERROR, - STATUS_FILE_CORRUPT_ERROR, - 0, 0, 0, 0, 0, 0, 0, 0 }; -#endif - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_CDDATA) - -// -// Global data structures -// - -CD_DATA CdData; -FAST_IO_DISPATCH CdFastIoDispatch; - -// -// Reserved directory strings. -// - -WCHAR CdUnicodeSelfArray[] = { L'.' }; -WCHAR CdUnicodeParentArray[] = { L'.', L'.' }; - -UNICODE_STRING CdUnicodeDirectoryNames[] = { - { 2, 2, CdUnicodeSelfArray}, - { 4, 4, CdUnicodeParentArray} -}; - -// -// Volume descriptor identifier strings. -// - -CHAR CdHsgId[] = { 'C', 'D', 'R', 'O', 'M' }; -CHAR CdIsoId[] = { 'C', 'D', '0', '0', '1' }; -CHAR CdXaId[] = { 'C', 'D', '-', 'X', 'A', '0', '0', '1' }; - -// -// Volume label for audio disks. -// - -WCHAR CdAudioLabel[] = { L'A', L'u', L'd', L'i', L'o', L' ', L'C', L'D' }; -USHORT CdAudioLabelLength = sizeof( CdAudioLabel ); - -// -// Pseudo file names for audio disks. -// - -CHAR CdAudioFileName[] = { 'T', 'r', 'a', 'c', 'k', '0', '0', '.', 'c', 'd', 'a' }; -UCHAR CdAudioFileNameLength = sizeof( CdAudioFileName ); -ULONG CdAudioDirentSize = FIELD_OFFSET( RAW_DIRENT, FileId ) + sizeof( CdAudioFileName ) + sizeof( SYSTEM_USE_XA ); -ULONG CdAudioDirentsPerSector = SECTOR_SIZE / (FIELD_OFFSET( RAW_DIRENT, FileId ) + sizeof( CdAudioFileName ) + sizeof( SYSTEM_USE_XA )); -ULONG CdAudioSystemUseOffset = FIELD_OFFSET( RAW_DIRENT, FileId ) + sizeof( CdAudioFileName ); - -// -// Escape sequences for mounting Unicode volumes. -// - -PCHAR CdJolietEscape[] = { "%/@", "%/C", "%/E" }; - -// -// Audio Play Files consist completely of this header block. These -// files are readable in the root of any audio disc regardless of -// the capabilities of the drive. -// -// The "Unique Disk ID Number" is a calculated value consisting of -// a combination of parameters, including the number of tracks and -// the starting locations of those tracks. -// -// Applications interpreting CDDA RIFF files should be advised that -// additional RIFF file chunks may be added to this header in the -// future in order to add information, such as the disk and song title. -// - -LONG CdAudioPlayHeader[] = { - 0x46464952, // Chunk ID = 'RIFF' - 4 * 11 - 8, // Chunk Size = (file size - 8) - 0x41444443, // 'CDDA' - 0x20746d66, // 'fmt ' - 24, // Chunk Size (of 'fmt ' subchunk) = 24 - 0x00000001, // WORD Format Tag, WORD Track Number - 0x00000000, // DWORD Unique Disk ID Number - 0x00000000, // DWORD Track Starting Sector (LBN) - 0x00000000, // DWORD Track Length (LBN count) - 0x00000000, // DWORD Track Starting Sector (MSF) - 0x00000000 // DWORD Track Length (MSF) -}; - -// Audio Philes begin with this header block to identify the data as a -// PCM waveform. AudioPhileHeader is coded as if it has no data included -// in the waveform. Data must be added in 2352-byte multiples. -// -// Fields marked 'ADJUST' need to be adjusted based on the size of the -// data: Add (nSectors*2352) to the DWORDs at offsets 1*4 and 10*4. -// -// File Size of TRACK??.WAV = nSectors*2352 + sizeof(AudioPhileHeader) -// RIFF('WAVE' fmt(1, 2, 44100, 176400, 16, 4) data( ) -// -// The number of sectors in a CD-XA CD-DA file is (DataLen/2048). -// CDFS will expose these files to applications as if they were just -// 'WAVE' files, adjusting the file size so that the RIFF file is valid. -// -// NT NOTE: We do not do any fidelity adjustment. These are presented as raw -// 2352 byte sectors - 95 has the glimmer of an idea to allow CDFS to expose -// the CDXA CDDA data at different sampling rates in a virtual directory -// structure, but we will never do that. -// - -LONG CdXAAudioPhileHeader[] = { - 0x46464952, // Chunk ID = 'RIFF' - -8, // Chunk Size = (file size - 8) ADJUST1 - 0x45564157, // 'WAVE' - 0x20746d66, // 'fmt ' - 16, // Chunk Size (of 'fmt ' subchunk) = 16 - 0x00020001, // WORD Format Tag WORD nChannels - 44100, // DWORD nSamplesPerSecond - 2352 * 75, // DWORD nAvgBytesPerSec - 0x00100004, // WORD nBlockAlign WORD nBitsPerSample - 0x61746164, // 'data' - -44 // ADJUST2 -}; - -// -// XA Files begin with this RIFF header block to identify the data as -// raw CD-XA sectors. Data must be added in 2352-byte multiples. -// -// This header is added to all CD-XA files which are marked as having -// mode2form2 sectors. -// -// Fields marked 'ADJUST' need to be adjusted based on the size of the -// data: Add file size to the marked DWORDS. -// -// File Size of TRACK??.WAV = nSectors*2352 + sizeof(XAFileHeader) -// -// RIFF('CDXA' FMT(Owner, Attr, 'X', 'A', FileNum, 0) data ( ) -// - -LONG CdXAFileHeader[] = { - 0x46464952, // Chunk ID = 'RIFF' - -8, // Chunk Size = (file size - 8) ADJUST - 0x41584443, // 'CDXA' - 0x20746d66, // 'fmt ' - 16, // Chunk Size (of CDXA chunk) = 16 - 0, // DWORD Owner ID - 0x41580000, // WORD Attributes - // BYTE Signature byte 1 'X' - // BYTE Signature byte 2 'A' - 0, // BYTE File Number - 0, // BYTE Reserved[7] - 0x61746164, // 'data' - -44 // ADJUST -}; - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdFastIoCheckIfPossible) -#pragma alloc_text(PAGE, CdSerial32) -#endif - - -NTSTATUS -CdFsdDispatch ( - IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the driver entry to all of the Fsd dispatch points. - - Conceptually the Io routine will call this routine on all requests - to the file system. We case on the type of request and invoke the - correct handler for this type of request. There is an exception filter - to catch any exceptions in the CDFS code as well as the CDFS process - exception routine. - - This routine allocates and initializes the IrpContext for this request as - well as updating the top-level thread context as necessary. We may loop - in this routine if we need to retry the request for any reason. The - status code STATUS_CANT_WAIT is used to indicate this. Suppose the disk - in the drive has changed. An Fsd request will proceed normally until it - recognizes this condition. STATUS_VERIFY_REQUIRED is raised at that point - and the exception code will handle the verify and either return - STATUS_CANT_WAIT or STATUS_PENDING depending on whether the request was - posted. - -Arguments: - - VolumeDeviceObject - Supplies the volume device object for this request - - Irp - Supplies the Irp being processed - -Return Value: - - NTSTATUS - The FSD status for the IRP - ---*/ - -{ - THREAD_CONTEXT ThreadContext; - PIRP_CONTEXT IrpContext = NULL; - BOOLEAN Wait; - -#ifdef CD_SANITY - PVOID PreviousTopLevel; -#endif - - NTSTATUS Status; - -#if DBG - - KIRQL SaveIrql = KeGetCurrentIrql(); - -#endif - - ASSERT_OPTIONAL_IRP( Irp ); - - FsRtlEnterFileSystem(); - -#ifdef CD_SANITY - PreviousTopLevel = IoGetTopLevelIrp(); -#endif - - // - // Loop until this request has been completed or posted. - // - - do { - - // - // Use a try-except to handle the exception cases. - // - - try { - - // - // If the IrpContext is NULL then this is the first pass through - // this loop. - // - - if (IrpContext == NULL) { - - // - // Decide if this request is waitable an allocate the IrpContext. - // If the file object in the stack location is NULL then this - // is a mount which is always waitable. Otherwise we look at - // the file object flags. - // - - if (IoGetCurrentIrpStackLocation( Irp )->FileObject == NULL) { - - Wait = TRUE; - - } else { - - Wait = CanFsdWait( Irp ); - } - - IrpContext = CdCreateIrpContext( Irp, Wait ); - - // - // Update the thread context information. - // - - CdSetThreadContext( IrpContext, &ThreadContext ); - -#ifdef CD_SANITY - ASSERT( !CdTestTopLevel || - SafeNodeType( IrpContext->TopLevel ) == CDFS_NTC_IRP_CONTEXT ); -#endif - - // - // Otherwise cleanup the IrpContext for the retry. - // - - } else { - - // - // Set the MORE_PROCESSING flag to make sure the IrpContext - // isn't inadvertently deleted here. Then cleanup the - // IrpContext to perform the retry. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); - CdCleanupIrpContext( IrpContext, FALSE ); - } - - // - // Case on the major irp code. - // - - switch (IrpContext->MajorFunction) { - - case IRP_MJ_CREATE : - - Status = CdCommonCreate( IrpContext, Irp ); - break; - - case IRP_MJ_CLOSE : - - Status = CdCommonClose( IrpContext, Irp ); - break; - - case IRP_MJ_READ : - - // - // If this is an Mdl complete request, don't go through - // common read. - // - - if (FlagOn( IrpContext->MinorFunction, IRP_MN_COMPLETE )) { - - Status = CdCompleteMdl( IrpContext, Irp ); - - } else { - - Status = CdCommonRead( IrpContext, Irp ); - } - - break; - - case IRP_MJ_QUERY_INFORMATION : - - Status = CdCommonQueryInfo( IrpContext, Irp ); - break; - - case IRP_MJ_SET_INFORMATION : - - Status = CdCommonSetInfo( IrpContext, Irp ); - break; - - case IRP_MJ_QUERY_VOLUME_INFORMATION : - - Status = CdCommonQueryVolInfo( IrpContext, Irp ); - break; - - case IRP_MJ_DIRECTORY_CONTROL : - - Status = CdCommonDirControl( IrpContext, Irp ); - break; - - case IRP_MJ_FILE_SYSTEM_CONTROL : - - Status = CdCommonFsControl( IrpContext, Irp ); - break; - - case IRP_MJ_DEVICE_CONTROL : - - Status = CdCommonDevControl( IrpContext, Irp ); - break; - - case IRP_MJ_LOCK_CONTROL : - - Status = CdCommonLockControl( IrpContext, Irp ); - break; - - case IRP_MJ_CLEANUP : - - Status = CdCommonCleanup( IrpContext, Irp ); - break; - - case IRP_MJ_PNP : - - Status = CdCommonPnp( IrpContext, Irp ); - break; - - default : - - Status = STATUS_INVALID_DEVICE_REQUEST; - CdCompleteRequest( IrpContext, Irp, Status ); - } - - } except( CdExceptionFilter( IrpContext, GetExceptionInformation() )) { - - Status = CdProcessException( IrpContext, Irp, GetExceptionCode() ); - } - - } while (Status == STATUS_CANT_WAIT); - -#ifdef CD_SANITY - ASSERT( !CdTestTopLevel || - (PreviousTopLevel == IoGetTopLevelIrp()) ); -#endif - - FsRtlExitFileSystem(); - - ASSERT( SaveIrql == KeGetCurrentIrql( )); - - return Status; -} - -#ifdef CD_SANITY - -VOID -CdRaiseStatusEx( - IN PIRP_CONTEXT IrpContext, - IN NTSTATUS Status, - IN BOOLEAN NormalizeStatus, - IN OPTIONAL ULONG FileId, - IN OPTIONAL ULONG Line - ) -{ - BOOLEAN BreakIn = FALSE; - - AssertVerifyDevice( IrpContext, Status); - - if (CdTraceRaises) { - - DbgPrint( "%p CdRaiseStatusEx 0x%x @ fid %d, line %d\n", PsGetCurrentThread(), Status, FileId, Line); - } - - if (CdTestRaisedStatus && !CdBreakOnAnyRaise) { - - ULONG Index; - - for (Index = 0; - Index < (sizeof( CdInterestingExceptionCodes) / sizeof( CdInterestingExceptionCodes[0])); - Index++) { - - if ((STATUS_SUCCESS != CdInterestingExceptionCodes[Index]) && - (CdInterestingExceptionCodes[Index] == Status)) { - - BreakIn = TRUE; - break; - } - } - } - - if (BreakIn || CdBreakOnAnyRaise) { - - DbgPrint( "CDFS: Breaking on raised status %08x (BI=%d,BA=%d)\n", Status, BreakIn, CdBreakOnAnyRaise); - DbgPrint( "CDFS: (FILEID %d LINE %d)\n", FileId, Line); - DbgPrint( "CDFS: Contact CDFS.SYS component owner for triage.\n"); - DbgPrint( "CDFS: 'eb %p 0;eb %p 0' to disable this alert.\n", &CdTestRaisedStatus, &CdBreakOnAnyRaise); - - DbgBreakPoint(); - } - - if (NormalizeStatus) { - - IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR); - } - else { - - IrpContext->ExceptionStatus = Status; - } - - IrpContext->RaisedAtLineFile = (FileId << 16) | Line; - - ExRaiseStatus( IrpContext->ExceptionStatus); -} - -#endif - -LONG -CdExceptionFilter ( - IN PIRP_CONTEXT IrpContext, - IN PEXCEPTION_POINTERS ExceptionPointer - ) - -/*++ - -Routine Description: - - This routine is used to decide whether we will handle a raised exception - status. If CDFS explicitly raised an error then this status is already - in the IrpContext. We choose which is the correct status code and - either indicate that we will handle the exception or bug-check the system. - -Arguments: - - ExceptionCode - Supplies the exception code to being checked. - -Return Value: - - ULONG - returns EXCEPTION_EXECUTE_HANDLER or bugchecks - ---*/ - -{ - NTSTATUS ExceptionCode; - BOOLEAN TestStatus = TRUE; - - ASSERT_OPTIONAL_IRP_CONTEXT( IrpContext ); - - ExceptionCode = ExceptionPointer->ExceptionRecord->ExceptionCode; - - // - // If the exception is STATUS_IN_PAGE_ERROR, get the I/O error code - // from the exception record. - // - - if ((ExceptionCode == STATUS_IN_PAGE_ERROR) && - (ExceptionPointer->ExceptionRecord->NumberParameters >= 3)) { - - ExceptionCode = - (NTSTATUS)ExceptionPointer->ExceptionRecord->ExceptionInformation[2]; - } - - // - // If there is an Irp context then check which status code to use. - // - - if (ARGUMENT_PRESENT( IrpContext )) { - - if (IrpContext->ExceptionStatus == STATUS_SUCCESS) { - - // - // Store the real status into the IrpContext. - // - - IrpContext->ExceptionStatus = ExceptionCode; - - } else { - - // - // No need to test the status code if we raised it ourselves. - // - - TestStatus = FALSE; - } - } - - AssertVerifyDevice( IrpContext, IrpContext->ExceptionStatus ); - - // - // Bug check if this status is not supported. - // - - if (TestStatus && !FsRtlIsNtstatusExpected( ExceptionCode )) { - - CdBugCheck( (ULONG_PTR) ExceptionPointer->ExceptionRecord, - (ULONG_PTR) ExceptionPointer->ContextRecord, - (ULONG_PTR) ExceptionPointer->ExceptionRecord->ExceptionAddress ); - - } - - return EXCEPTION_EXECUTE_HANDLER; -} - - -NTSTATUS -CdProcessException ( - IN PIRP_CONTEXT IrpContext OPTIONAL, - IN PIRP Irp, - IN NTSTATUS ExceptionCode - ) - -/*++ - -Routine Description: - - This routine processes an exception. It either completes the request - with the exception status in the IrpContext, sends this off to the Fsp - workque or causes it to be retried in the current thread if a verification - is needed. - - If the volume needs to be verified (STATUS_VERIFY_REQUIRED) and we can - do the work in the current thread we will translate the status code - to STATUS_CANT_WAIT to indicate that we need to retry the request. - -Arguments: - - Irp - Supplies the Irp being processed - - ExceptionCode - Supplies the normalized exception status being handled - -Return Value: - - NTSTATUS - Returns the results of either posting the Irp or the - saved completion status. - ---*/ - -{ - PDEVICE_OBJECT Device; - PVPB Vpb; - PETHREAD Thread; - - ASSERT_OPTIONAL_IRP_CONTEXT( IrpContext ); - ASSERT_IRP( Irp ); - - // - // If there is not an irp context, then complete the request with the - // current status code. - // - - if (!ARGUMENT_PRESENT( IrpContext )) { - - CdCompleteRequest( NULL, Irp, ExceptionCode ); - return ExceptionCode; - } - - // - // Get the real exception status from the IrpContext. - // - - ExceptionCode = IrpContext->ExceptionStatus; - - // - // If we are not a top level request then we just complete the request - // with the current status code. - // - - if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL )) { - - CdCompleteRequest( IrpContext, Irp, ExceptionCode ); - return ExceptionCode; - } - - // - // Check if we are posting this request. One of the following must be true - // if we are to post a request. - // - // - Status code is STATUS_CANT_WAIT and the request is asynchronous - // or we are forcing this to be posted. - // - // - Status code is STATUS_VERIFY_REQUIRED and we are at APC level - // or higher. Can't wait for IO in the verify path in this case. - // - // Set the MORE_PROCESSING flag in the IrpContext to keep if from being - // deleted if this is a retryable condition. - // - // - // Note that (children of) CdFsdPostRequest can raise (Mdl allocation). - // - - try { - - if (ExceptionCode == STATUS_CANT_WAIT) { - - if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST )) { - - ExceptionCode = CdFsdPostRequest( IrpContext, Irp ); - } - - } else if (ExceptionCode == STATUS_VERIFY_REQUIRED) { - - if (KeGetCurrentIrql() >= APC_LEVEL) { - - ExceptionCode = CdFsdPostRequest( IrpContext, Irp ); - } - } - } - except( CdExceptionFilter( IrpContext, GetExceptionInformation() )) { - - ExceptionCode = GetExceptionCode(); - } - - // - // If we posted the request or our caller will retry then just return here. - // - - if ((ExceptionCode == STATUS_PENDING) || - (ExceptionCode == STATUS_CANT_WAIT)) { - - return ExceptionCode; - } - - ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); - - // - // Store this error into the Irp for posting back to the Io system. - // - - Irp->IoStatus.Status = ExceptionCode; - - if (IoIsErrorUserInduced( ExceptionCode )) { - - // - // Check for the various error conditions that can be caused by, - // and possibly resolved my the user. - // - - if (ExceptionCode == STATUS_VERIFY_REQUIRED) { - - // - // Now we are at the top level file system entry point. - // - // If we have already posted this request then the device to - // verify is in the original thread. Find this via the Irp. - // - - Device = IoGetDeviceToVerify( Irp->Tail.Overlay.Thread ); - IoSetDeviceToVerify( Irp->Tail.Overlay.Thread, NULL ); - - // - // If there is no device in that location then check in the - // current thread. - // - - if (Device == NULL) { - - Device = IoGetDeviceToVerify( PsGetCurrentThread() ); - IoSetDeviceToVerify( PsGetCurrentThread(), NULL ); - - ASSERT( Device != NULL ); - - // - // Let's not BugCheck just because the driver messes up. - // - - if (Device == NULL) { - - ExceptionCode = STATUS_DRIVER_INTERNAL_ERROR; - - CdCompleteRequest( IrpContext, Irp, ExceptionCode ); - - return ExceptionCode; - } - } - - // - // CdPerformVerify() will do the right thing with the Irp. - // If we return STATUS_CANT_WAIT then the current thread - // can retry the request. - // - - return CdPerformVerify( IrpContext, Irp, Device ); - } - - // - // The other user induced conditions generate an error unless - // they have been disabled for this request. - // - - if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS )) { - - CdCompleteRequest( IrpContext, Irp, ExceptionCode ); - - return ExceptionCode; - - } - // - // Generate a pop-up. - // - else { - - if (IoGetCurrentIrpStackLocation( Irp )->FileObject != NULL) { - - Vpb = IoGetCurrentIrpStackLocation( Irp )->FileObject->Vpb; - - } else { - - Vpb = NULL; - } - - // - // The device to verify is either in my thread local storage - // or that of the thread that owns the Irp. - // - - Thread = Irp->Tail.Overlay.Thread; - Device = IoGetDeviceToVerify( Thread ); - - if (Device == NULL) { - - Thread = PsGetCurrentThread(); - Device = IoGetDeviceToVerify( Thread ); - - ASSERT( Device != NULL ); - - // - // Let's not BugCheck just because the driver messes up. - // - - if (Device == NULL) { - - CdCompleteRequest( IrpContext, Irp, ExceptionCode ); - - return ExceptionCode; - } - } - - // - // This routine actually causes the pop-up. It usually - // does this by queuing an APC to the callers thread, - // but in some cases it will complete the request immediately, - // so it is very important to IoMarkIrpPending() first. - // - - IoMarkIrpPending( Irp ); - IoRaiseHardError( Irp, Vpb, Device ); - - // - // We will be handing control back to the caller here, so - // reset the saved device object. - // - - IoSetDeviceToVerify( Thread, NULL ); - - // - // The Irp will be completed by Io or resubmitted. In either - // case we must clean up the IrpContext here. - // - - CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); - return STATUS_PENDING; - } - } - - // - // This is just a run of the mill error. - // - - CdCompleteRequest( IrpContext, Irp, ExceptionCode ); - - return ExceptionCode; -} - - -VOID -CdCompleteRequest ( - IN PIRP_CONTEXT IrpContext OPTIONAL, - IN PIRP Irp OPTIONAL, - IN NTSTATUS Status - ) - -/*++ - -Routine Description: - - This routine completes a Irp and cleans up the IrpContext. Either or - both of these may not be specified. - -Arguments: - - Irp - Supplies the Irp being processed. - - Status - Supplies the status to complete the Irp with - -Return Value: - - None. - ---*/ - -{ - ASSERT_OPTIONAL_IRP_CONTEXT( IrpContext ); - ASSERT_OPTIONAL_IRP( Irp ); - - // - // Cleanup the IrpContext if passed in here. - // - - if (ARGUMENT_PRESENT( IrpContext )) { - - CdCleanupIrpContext( IrpContext, FALSE ); - } - - // - // If we have an Irp then complete the irp. - // - - if (ARGUMENT_PRESENT( Irp )) { - - // - // Clear the information field in case we have used this Irp - // internally. - // - - if (NT_ERROR( Status ) && - FlagOn( Irp->Flags, IRP_INPUT_OPERATION )) { - - Irp->IoStatus.Information = 0; - } - - Irp->IoStatus.Status = Status; - - AssertVerifyDeviceIrp( Irp ); - - IoCompleteRequest( Irp, IO_CD_ROM_INCREMENT ); - } - - return; -} - - -VOID -CdSetThreadContext ( - IN PIRP_CONTEXT IrpContext, - IN PTHREAD_CONTEXT ThreadContext - ) - -/*++ - -Routine Description: - - This routine is called at each Fsd/Fsp entry point set up the IrpContext - and thread local storage to track top level requests. If there is - not a Cdfs context in the thread local storage then we use the input one. - Otherwise we use the one already there. This routine also updates the - IrpContext based on the state of the top-level context. - - If the TOP_LEVEL flag in the IrpContext is already set when we are called - then we force this request to appear top level. - -Arguments: - - ThreadContext - Address on stack for local storage if not already present. - - ForceTopLevel - We force this request to appear top level regardless of - any previous stack value. - -Return Value: - - None - ---*/ - -{ - PTHREAD_CONTEXT CurrentThreadContext; - ULONG_PTR StackTop; - ULONG_PTR StackBottom; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - - // - // Get the current top-level irp out of the thread storage. - // If NULL then this is the top-level request. - // - - CurrentThreadContext = (PTHREAD_CONTEXT) IoGetTopLevelIrp(); - - if (CurrentThreadContext == NULL) { - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL ); - } - - // - // Initialize the input context unless we are using the current - // thread context block. We use the new block if our caller - // specified this or the existing block is invalid. - // - // The following must be true for the current to be a valid Cdfs context. - // - // Structure must lie within current stack. - // Address must be ULONG aligned. - // Cdfs signature must be present. - // - // If this is not a valid Cdfs context then use the input thread - // context and store it in the top level context. - // - - IoGetStackLimits( &StackTop, &StackBottom); - - if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL ) || - (((ULONG_PTR) CurrentThreadContext > StackBottom - sizeof( THREAD_CONTEXT )) || - ((ULONG_PTR) CurrentThreadContext <= StackTop) || - FlagOn( (ULONG_PTR) CurrentThreadContext, 0x3 ) || - (CurrentThreadContext->Cdfs != 0x53464443))) { - - ThreadContext->Cdfs = 0x53464443; - ThreadContext->SavedTopLevelIrp = (PIRP) CurrentThreadContext; - ThreadContext->TopLevelIrpContext = IrpContext; - IoSetTopLevelIrp( (PIRP) ThreadContext ); - - IrpContext->TopLevel = IrpContext; - IrpContext->ThreadContext = ThreadContext; - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS ); - - // - // Otherwise use the IrpContext in the thread context. - // - - } else { - - IrpContext->TopLevel = CurrentThreadContext->TopLevelIrpContext; - } - - return; -} - - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastIoCheckIfPossible ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - IN BOOLEAN CheckForReadOperation, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ) - -/*++ - -Routine Description: - - This routine checks if fast i/o is possible for a read/write operation - -Arguments: - - FileObject - Supplies the file object used in the query - - FileOffset - Supplies the starting byte offset for the read/write operation - - Length - Supplies the length, in bytes, of the read/write operation - - Wait - Indicates if we can wait - - LockKey - Supplies the lock key - - CheckForReadOperation - Indicates if this is a check for a read or write - operation - - IoStatus - Receives the status of the operation if our return value is - FastIoReturnError - -Return Value: - - BOOLEAN - TRUE if fast I/O is possible and FALSE if the caller needs - to take the long route. - ---*/ - -{ - PFCB Fcb; - TYPE_OF_OPEN TypeOfOpen; - LARGE_INTEGER LargeLength; - - PAGED_CODE(); - - // - // Decode the type of file object we're being asked to process and - // make sure that is is only a user file open. - // - - TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb ); - - if ((TypeOfOpen != UserFileOpen) || !CheckForReadOperation) { - - IoStatus->Status = STATUS_INVALID_PARAMETER; - return TRUE; - } - - LargeLength.QuadPart = Length; - - // - // Check whether the file locks will allow for fast io. - // - - if ((Fcb->FileLock == NULL) || - FsRtlFastCheckLockForRead( Fcb->FileLock, - FileOffset, - &LargeLength, - LockKey, - FileObject, - PsGetCurrentProcess() )) { - - return TRUE; - } - - return FALSE; -} - - -ULONG -CdSerial32 ( - IN PCHAR Buffer, - IN ULONG ByteCount - ) -/*++ - -Routine Description: - - This routine is called to generate a 32 bit serial number. This is - done by doing four separate checksums into an array of bytes and - then treating the bytes as a ULONG. - -Arguments: - - Buffer - Pointer to the buffer to generate the ID for. - - ByteCount - Number of bytes in the buffer. - -Return Value: - - ULONG - The 32 bit serial number. - ---*/ - -{ - union { - UCHAR Bytes[4]; - ULONG SerialId; - } Checksum; - - PAGED_CODE(); - - // - // Initialize the serial number. - // - - Checksum.SerialId = 0; - - // - // Continue while there are more bytes to use. - // - - while (ByteCount--) { - - // - // Increment this sub-checksum. - // - - Checksum.Bytes[ByteCount & 0x3] += *(Buffer++); - } - - // - // Return the checksums as a ULONG. - // - - return Checksum.SerialId; -} - - diff --git a/reactos/drivers/filesystems/cdfs_new/cddata.h b/reactos/drivers/filesystems/cdfs_new/cddata.h deleted file mode 100755 index 0577a4ca302..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/cddata.h +++ /dev/null @@ -1,278 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - CdData.c - -Abstract: - - This module declares the global data used by the Cdfs file system. - - ---*/ - -#ifndef _CDDATA_ -#define _CDDATA_ - -// -// Global data structures -// - -extern CD_DATA CdData; -extern FAST_IO_DISPATCH CdFastIoDispatch; - -// -// Global constants -// - -// -// This is the number of times a mounted Vcb will be referenced on behalf -// of the system. The counts include the following references. -// -// 1 reference - shows the volume is mounted -// 1 reference - 1 for VolumeDasdFcb. -// 2 references - 1 for RootIndexFcb, 1 for internal stream. -// 2 references - 1 for PathTableFcb, 1 for internal stream. -// -// For user references we add one for the reference in each of the internal -// Fcb's. -// - -#define CDFS_RESIDUAL_REFERENCE (6) -#define CDFS_RESIDUAL_USER_REFERENCE (3) - -// -// Reserved directory strings -// - -extern WCHAR CdUnicodeSelfArray[]; -extern WCHAR CdUnicodeParentArray[]; - -extern UNICODE_STRING CdUnicodeDirectoryNames[]; - -// -// Volume descriptor identifier strings. -// - -extern CHAR CdHsgId[]; -extern CHAR CdIsoId[]; -extern CHAR CdXaId[]; - -// -// Volume label for audio disks. -// - -extern WCHAR CdAudioLabel[]; -extern USHORT CdAudioLabelLength; - -// -// Pseudo file names for audio disks. -// - -extern CHAR CdAudioFileName[]; -extern UCHAR CdAudioFileNameLength; -extern ULONG CdAudioDirentSize; -extern ULONG CdAudioDirentsPerSector; -extern ULONG CdAudioSystemUseOffset; - -#define AUDIO_NAME_ONES_OFFSET (6) -#define AUDIO_NAME_TENS_OFFSET (5) - -// -// Escape sequences for mounting Unicode volumes. -// - -extern PCHAR CdJolietEscape[]; - -// -// Hardcoded header for RIFF files. -// - -extern LONG CdXAFileHeader[]; -extern LONG CdAudioPlayHeader[]; -extern LONG CdXAAudioPhileHeader[]; - - -// -// Turn on pseudo-asserts if CD_FREE_ASSERTS is defined. -// - -#if !DBG -#ifdef CD_FREE_ASSERTS -#undef ASSERT -#undef ASSERTMSG -#define ASSERT(exp) if (!(exp)) { extern BOOLEAN KdDebuggerEnabled; DbgPrint("%s:%d %s\n",__FILE__,__LINE__,#exp); if (KdDebuggerEnabled) { DbgBreakPoint(); } } -#define ASSERTMSG(msg,exp) if (!(exp)) { extern BOOLEAN KdDebuggerEnabled; DbgPrint("%s:%d %s %s\n",__FILE__,__LINE__,msg,#exp); if (KdDebuggerEnabled) { DbgBreakPoint(); } } -#endif -#endif - - -// -// The following assertion macros ensure that the indicated structure -// is valid -// -// ASSERT_STRUCT( IN PVOID Struct, IN CSHORT NodeType ); -// ASSERT_OPTIONAL_STRUCT( IN PVOID Struct OPTIONAL, IN CSHORT NodeType ); -// -// ASSERT_VCB( IN PVCB Vcb ); -// ASSERT_OPTIONAL_VCB( IN PVCB Vcb OPTIONAL ); -// -// ASSERT_FCB( IN PFCB Fcb ); -// ASSERT_OPTIONAL_FCB( IN PFCB Fcb OPTIONAL ); -// -// ASSERT_FCB_NONPAGED( IN PFCB_NONPAGED FcbNonpaged ); -// ASSERT_OPTIONAL_FCB( IN PFCB_NONPAGED FcbNonpaged OPTIONAL ); -// -// ASSERT_CCB( IN PSCB Ccb ); -// ASSERT_OPTIONAL_CCB( IN PSCB Ccb OPTIONAL ); -// -// ASSERT_IRP_CONTEXT( IN PIRP_CONTEXT IrpContext ); -// ASSERT_OPTIONAL_IRP_CONTEXT( IN PIRP_CONTEXT IrpContext OPTIONAL ); -// -// ASSERT_IRP( IN PIRP Irp ); -// ASSERT_OPTIONAL_IRP( IN PIRP Irp OPTIONAL ); -// -// ASSERT_FILE_OBJECT( IN PFILE_OBJECT FileObject ); -// ASSERT_OPTIONAL_FILE_OBJECT( IN PFILE_OBJECT FileObject OPTIONAL ); -// -// The following macros are used to check the current thread owns -// the indicated resource -// -// ASSERT_EXCLUSIVE_RESOURCE( IN PERESOURCE Resource ); -// -// ASSERT_SHARED_RESOURCE( IN PERESOURCE Resource ); -// -// ASSERT_RESOURCE_NOT_MINE( IN PERESOURCE Resource ); -// -// The following macros are used to check whether the current thread -// owns the resoures in the given structures. -// -// ASSERT_EXCLUSIVE_CDDATA -// -// ASSERT_EXCLUSIVE_VCB( IN PVCB Vcb ); -// -// ASSERT_SHARED_VCB( IN PVCB Vcb ); -// -// ASSERT_EXCLUSIVE_FCB( IN PFCB Fcb ); -// -// ASSERT_SHARED_FCB( IN PFCB Fcb ); -// -// ASSERT_EXCLUSIVE_FILE( IN PFCB Fcb ); -// -// ASSERT_SHARED_FILE( IN PFCB Fcb ); -// -// ASSERT_LOCKED_VCB( IN PVCB Vcb ); -// -// ASSERT_NOT_LOCKED_VCB( IN PVCB Vcb ); -// -// ASSERT_LOCKED_FCB( IN PFCB Fcb ); -// -// ASSERT_NOT_LOCKED_FCB( IN PFCB Fcb ); -// - -// -// Turn on the sanity checks if this is DBG or CD_FREE_ASSERTS -// - -#if DBG -#undef CD_SANITY -#define CD_SANITY -#endif - -#ifdef CD_SANITY - -#define ASSERT_STRUCT(S,T) ASSERT( SafeNodeType( S ) == (T) ) -#define ASSERT_OPTIONAL_STRUCT(S,T) ASSERT( ((S) == NULL) || (SafeNodeType( S ) == (T)) ) - -#define ASSERT_VCB(V) ASSERT_STRUCT( (V), CDFS_NTC_VCB ) -#define ASSERT_OPTIONAL_VCB(V) ASSERT_OPTIONAL_STRUCT( (V), CDFS_NTC_VCB ) - -#define ASSERT_FCB(F) \ - ASSERT( (SafeNodeType( F ) == CDFS_NTC_FCB_DATA ) || \ - (SafeNodeType( F ) == CDFS_NTC_FCB_INDEX ) || \ - (SafeNodeType( F ) == CDFS_NTC_FCB_PATH_TABLE ) ) - -#define ASSERT_OPTIONAL_FCB(F) \ - ASSERT( ((F) == NULL) || \ - (SafeNodeType( F ) == CDFS_NTC_FCB_DATA ) || \ - (SafeNodeType( F ) == CDFS_NTC_FCB_INDEX ) || \ - (SafeNodeType( F ) == CDFS_NTC_FCB_PATH_TABLE ) ) - -#define ASSERT_FCB_NONPAGED(FN) ASSERT_STRUCT( (FN), CDFS_NTC_FCB_NONPAGED ) -#define ASSERT_OPTIONAL_FCB_NONPAGED(FN) ASSERT_OPTIONAL_STRUCT( (FN), CDFS_NTC_FCB_NONPAGED ) - -#define ASSERT_CCB(C) ASSERT_STRUCT( (C), CDFS_NTC_CCB ) -#define ASSERT_OPTIONAL_CCB(C) ASSERT_OPTIONAL_STRUCT( (C), CDFS_NTC_CCB ) - -#define ASSERT_IRP_CONTEXT(IC) ASSERT_STRUCT( (IC), CDFS_NTC_IRP_CONTEXT ) -#define ASSERT_OPTIONAL_IRP_CONTEXT(IC) ASSERT_OPTIONAL_STRUCT( (IC), CDFS_NTC_IRP_CONTEXT ) - -#define ASSERT_IRP(I) ASSERT_STRUCT( (I), IO_TYPE_IRP ) -#define ASSERT_OPTIONAL_IRP(I) ASSERT_OPTIONAL_STRUCT( (I), IO_TYPE_IRP ) - -#define ASSERT_FILE_OBJECT(FO) ASSERT_STRUCT( (FO), IO_TYPE_FILE ) -#define ASSERT_OPTIONAL_FILE_OBJECT(FO) ASSERT_OPTIONAL_STRUCT( (FO), IO_TYPE_FILE ) - -#define ASSERT_EXCLUSIVE_RESOURCE(R) ASSERT( ExIsResourceAcquiredExclusiveLite( R )) - -#define ASSERT_SHARED_RESOURCE(R) ASSERT( ExIsResourceAcquiredSharedLite( R )) - -#define ASSERT_RESOURCE_NOT_MINE(R) ASSERT( !ExIsResourceAcquiredSharedLite( R )) - -#define ASSERT_EXCLUSIVE_CDDATA ASSERT( ExIsResourceAcquiredExclusiveLite( &CdData.DataResource )) -#define ASSERT_EXCLUSIVE_VCB(V) ASSERT( ExIsResourceAcquiredExclusiveLite( &(V)->VcbResource )) -#define ASSERT_SHARED_VCB(V) ASSERT( ExIsResourceAcquiredSharedLite( &(V)->VcbResource )) - -#define ASSERT_EXCLUSIVE_FCB(F) ASSERT( ExIsResourceAcquiredExclusiveLite( &(F)->FcbNonpaged->FcbResource )) -#define ASSERT_SHARED_FCB(F) ASSERT( ExIsResourceAcquiredSharedLite( &(F)->FcbNonpaged->FcbResource )) - -#define ASSERT_EXCLUSIVE_FILE(F) ASSERT( ExIsResourceAcquiredExclusiveLite( (F)->Resource )) -#define ASSERT_SHARED_FILE(F) ASSERT( ExIsResourceAcquiredSharedLite( (F)->Resource )) - -#define ASSERT_LOCKED_VCB(V) ASSERT( (V)->VcbLockThread == PsGetCurrentThread() ) -#define ASSERT_NOT_LOCKED_VCB(V) ASSERT( (V)->VcbLockThread != PsGetCurrentThread() ) - -#define ASSERT_LOCKED_FCB(F) ASSERT( !FlagOn( (F)->FcbState, FCB_STATE_IN_FCB_TABLE) || ((F)->FcbLockThread == PsGetCurrentThread())) -#define ASSERT_NOT_LOCKED_FCB(F) ASSERT( (F)->FcbLockThread != PsGetCurrentThread() ) - -#else - -#define DebugBreakOnStatus(S) { NOTHING; } - -#define ASSERT_STRUCT(S,T) { NOTHING; } -#define ASSERT_OPTIONAL_STRUCT(S,T) { NOTHING; } -#define ASSERT_VCB(V) { NOTHING; } -#define ASSERT_OPTIONAL_VCB(V) { NOTHING; } -#define ASSERT_FCB(F) { NOTHING; } -#define ASSERT_OPTIONAL_FCB(F) { NOTHING; } -#define ASSERT_FCB_NONPAGED(FN) { NOTHING; } -#define ASSERT_OPTIONAL_FCB(FN) { NOTHING; } -#define ASSERT_CCB(C) { NOTHING; } -#define ASSERT_OPTIONAL_CCB(C) { NOTHING; } -#define ASSERT_IRP_CONTEXT(IC) { NOTHING; } -#define ASSERT_OPTIONAL_IRP_CONTEXT(IC) { NOTHING; } -#define ASSERT_IRP(I) { NOTHING; } -#define ASSERT_OPTIONAL_IRP(I) { NOTHING; } -#define ASSERT_FILE_OBJECT(FO) { NOTHING; } -#define ASSERT_OPTIONAL_FILE_OBJECT(FO) { NOTHING; } -#define ASSERT_EXCLUSIVE_RESOURCE(R) { NOTHING; } -#define ASSERT_SHARED_RESOURCE(R) { NOTHING; } -#define ASSERT_RESOURCE_NOT_MINE(R) { NOTHING; } -#define ASSERT_EXCLUSIVE_CDDATA { NOTHING; } -#define ASSERT_EXCLUSIVE_VCB(V) { NOTHING; } -#define ASSERT_SHARED_VCB(V) { NOTHING; } -#define ASSERT_EXCLUSIVE_FCB(F) { NOTHING; } -#define ASSERT_SHARED_FCB(F) { NOTHING; } -#define ASSERT_EXCLUSIVE_FILE(F) { NOTHING; } -#define ASSERT_SHARED_FILE(F) { NOTHING; } -#define ASSERT_LOCKED_VCB(V) { NOTHING; } -#define ASSERT_NOT_LOCKED_VCB(V) { NOTHING; } -#define ASSERT_LOCKED_FCB(F) { NOTHING; } -#define ASSERT_NOT_LOCKED_FCB(F) { NOTHING; } - -#endif - -#endif // _CDDATA_ - diff --git a/reactos/drivers/filesystems/cdfs_new/cdfs.rbuild b/reactos/drivers/filesystems/cdfs_new/cdfs.rbuild deleted file mode 100644 index 6cfb1ee0a48..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/cdfs.rbuild +++ /dev/null @@ -1,36 +0,0 @@ - - - - - . - ntoskrnl - hal - allocsup.c - cachesup.c - cddata.c - cdinit.c - cleanup.c - close.c - create.c - devctrl.c - deviosup.c - dirctrl.c - dirsup.c - fileinfo.c - filobsup.c - fsctrl.c - fspdisp.c - lockctrl.c - namesup.c - pathsup.c - pnp.c - prefxsup.c - read.c - resrcsup.c - strucsup.c - verfysup.c - volinfo.c - workque.c - cdfs.rc - cdprocs.h - diff --git a/reactos/drivers/filesystems/cdfs_new/cdfs.rc b/reactos/drivers/filesystems/cdfs_new/cdfs.rc deleted file mode 100644 index 1cf70c60840..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/cdfs.rc +++ /dev/null @@ -1,7 +0,0 @@ -/* $Id: cdfs.rc 21710 2006-04-22 16:36:21Z tretiakov $ */ - -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ISO9660 Driver\0" -#define REACTOS_STR_INTERNAL_NAME "cdfs\0" -#define REACTOS_STR_ORIGINAL_FILENAME "cdfs.sys\0" -#include diff --git a/reactos/drivers/filesystems/cdfs_new/cdinit.c b/reactos/drivers/filesystems/cdfs_new/cdinit.c deleted file mode 100755 index f0faef6af39..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/cdinit.c +++ /dev/null @@ -1,372 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - CdInit.c - -Abstract: - - This module implements the DRIVER_INITIALIZATION routine for Cdfs - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_CDINIT) - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ); - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdUnload( - IN PDRIVER_OBJECT DriverObject - ); - -NTSTATUS -CdInitializeGlobalData ( - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT FileSystemDeviceObject - ); - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdShutdown ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(INIT, DriverEntry) -#pragma alloc_text(PAGE, CdUnload) -#pragma alloc_text(PAGE, CdShutdown) -#pragma alloc_text(INIT, CdInitializeGlobalData) -#endif - - -// -// Local support routine -// - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) - -/*++ - -Routine Description: - - This is the initialization routine for the Cdrom file system - device driver. This routine creates the device object for the FileSystem - device and performs all other driver initialization. - -Arguments: - - DriverObject - Pointer to driver object created by the system. - -Return Value: - - NTSTATUS - The function value is the final status from the initialization - operation. - ---*/ - -{ - NTSTATUS Status; - UNICODE_STRING UnicodeString; - PDEVICE_OBJECT CdfsFileSystemDeviceObject; - - // - // Create the device object. - // - - RtlInitUnicodeString( &UnicodeString, L"\\Cdfs" ); - - Status = IoCreateDevice( DriverObject, - 0, - &UnicodeString, - FILE_DEVICE_CD_ROM_FILE_SYSTEM, - 0, - FALSE, - &CdfsFileSystemDeviceObject ); - - if (!NT_SUCCESS( Status )) { - return Status; - } - DriverObject->DriverUnload = CdUnload; - // - // Note that because of the way data caching is done, we set neither - // the Direct I/O or Buffered I/O bit in DeviceObject->Flags. If - // data is not in the cache, or the request is not buffered, we may, - // set up for Direct I/O by hand. - // - - // - // Initialize the driver object with this driver's entry points. - // - // NOTE - Each entry in the dispatch table must have an entry in - // the Fsp/Fsd dispatch switch statements. - // - - DriverObject->MajorFunction[IRP_MJ_CREATE] = - DriverObject->MajorFunction[IRP_MJ_CLOSE] = - DriverObject->MajorFunction[IRP_MJ_READ] = - DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = - DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = - DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION]= - DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = - DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = - DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = - DriverObject->MajorFunction[IRP_MJ_CLEANUP] = - DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH) CdFsdDispatch; - DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = CdShutdown; - - DriverObject->FastIoDispatch = &CdFastIoDispatch; - - Status = IoRegisterShutdownNotification (CdfsFileSystemDeviceObject); - if (!NT_SUCCESS (Status)) { - IoDeleteDevice (CdfsFileSystemDeviceObject); - return Status; - } - - // - // Initialize the global data structures - // - - Status = CdInitializeGlobalData( DriverObject, CdfsFileSystemDeviceObject ); - if (!NT_SUCCESS (Status)) { - IoDeleteDevice (CdfsFileSystemDeviceObject); - return Status; - } - - // - // Register the file system as low priority with the I/O system. This will cause - // CDFS to receive mount requests after a) other filesystems currently registered - // and b) other normal priority filesystems that may be registered later. - // - - CdfsFileSystemDeviceObject->Flags |= DO_LOW_PRIORITY_FILESYSTEM; - - IoRegisterFileSystem( CdfsFileSystemDeviceObject ); - ObReferenceObject (CdfsFileSystemDeviceObject); - - // - // And return to our caller - // - - return( STATUS_SUCCESS ); -} - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdShutdown ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp - ) -/*++ - -Routine Description: - - This routine is the shutdown handler for CDFS. - -Arguments: - - DeviceObject - Supplies the registered device object for CDFS. - Irp - Shutdown IRP - - -Return Value: - - None. - ---*/ -{ - IoUnregisterFileSystem (DeviceObject); - IoDeleteDevice (CdData.FileSystemDeviceObject); - - CdCompleteRequest( NULL, Irp, STATUS_SUCCESS ); - return STATUS_SUCCESS; -} - - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdUnload( - IN PDRIVER_OBJECT DriverObject - ) -/*++ - -Routine Description: - - This routine unload routine for CDFS. - -Arguments: - - DriverObject - Supplies the driver object for CDFS. - -Return Value: - - None. - ---*/ -{ - PIRP_CONTEXT IrpContext; - - // - // Free any IRP contexts - // - while (1) { - IrpContext = (PIRP_CONTEXT) PopEntryList( &CdData.IrpContextList) ; - if (IrpContext == NULL) { - break; - } - CdFreePool(&IrpContext); - } - - IoFreeWorkItem (CdData.CloseItem); - ExDeleteResourceLite( &CdData.DataResource ); - ObDereferenceObject (CdData.FileSystemDeviceObject); -} - -// -// Local support routine -// - -NTSTATUS -CdInitializeGlobalData ( - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT FileSystemDeviceObject - ) - -/*++ - -Routine Description: - - This routine initializes the global cdfs data structures. - -Arguments: - - DriverObject - Supplies the driver object for CDFS. - - FileSystemDeviceObject - Supplies the device object for CDFS. - -Return Value: - - None. - ---*/ - -{ - // - // Start by initializing the FastIoDispatch Table. - // - - RtlZeroMemory( &CdFastIoDispatch, sizeof( FAST_IO_DISPATCH )); - - CdFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); - CdFastIoDispatch.FastIoCheckIfPossible = CdFastIoCheckIfPossible; // CheckForFastIo - CdFastIoDispatch.FastIoRead = FsRtlCopyRead; // Read - CdFastIoDispatch.FastIoQueryBasicInfo = CdFastQueryBasicInfo; // QueryBasicInfo - CdFastIoDispatch.FastIoQueryStandardInfo = CdFastQueryStdInfo; // QueryStandardInfo - CdFastIoDispatch.FastIoLock = CdFastLock; // Lock - CdFastIoDispatch.FastIoUnlockSingle = CdFastUnlockSingle; // UnlockSingle - CdFastIoDispatch.FastIoUnlockAll = CdFastUnlockAll; // UnlockAll - CdFastIoDispatch.FastIoUnlockAllByKey = CdFastUnlockAllByKey; // UnlockAllByKey - CdFastIoDispatch.AcquireFileForNtCreateSection = CdAcquireForCreateSection; - CdFastIoDispatch.ReleaseFileForNtCreateSection = CdReleaseForCreateSection; - CdFastIoDispatch.FastIoQueryNetworkOpenInfo = CdFastQueryNetworkInfo; // QueryNetworkInfo - - CdFastIoDispatch.MdlRead = FsRtlMdlReadDev; - CdFastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev; - CdFastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev; - CdFastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev; - - // - // Initialize the CdData structure. - // - - RtlZeroMemory( &CdData, sizeof( CD_DATA )); - - CdData.NodeTypeCode = CDFS_NTC_DATA_HEADER; - CdData.NodeByteSize = sizeof( CD_DATA ); - - CdData.DriverObject = DriverObject; - CdData.FileSystemDeviceObject = FileSystemDeviceObject; - - InitializeListHead( &CdData.VcbQueue ); - - ExInitializeResourceLite( &CdData.DataResource ); - - // - // Initialize the cache manager callback routines - // - - CdData.CacheManagerCallbacks.AcquireForLazyWrite = (PVOID)&CdAcquireForCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - CdData.CacheManagerCallbacks.ReleaseFromLazyWrite = (PVOID)&CdReleaseFromCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - CdData.CacheManagerCallbacks.AcquireForReadAhead = (PVOID)&CdAcquireForCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - CdData.CacheManagerCallbacks.ReleaseFromReadAhead = (PVOID)&CdReleaseFromCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - - CdData.CacheManagerVolumeCallbacks.AcquireForLazyWrite = &CdNoopAcquire; - CdData.CacheManagerVolumeCallbacks.ReleaseFromLazyWrite = &CdNoopRelease; - CdData.CacheManagerVolumeCallbacks.AcquireForReadAhead = &CdNoopAcquire; - CdData.CacheManagerVolumeCallbacks.ReleaseFromReadAhead = &CdNoopRelease; - - // - // Initialize the lock mutex and the async and delay close queues. - // - - ExInitializeFastMutex( &CdData.CdDataMutex ); - InitializeListHead( &CdData.AsyncCloseQueue ); - InitializeListHead( &CdData.DelayedCloseQueue ); - - CdData.CloseItem = IoAllocateWorkItem (FileSystemDeviceObject); - if (CdData.CloseItem == NULL) { - - ExDeleteResourceLite( &CdData.DataResource ); - return STATUS_INSUFFICIENT_RESOURCES; - } - // - // Do the initialization based on the system size. - // - - switch (MmQuerySystemSize()) { - - case MmSmallSystem: - - CdData.IrpContextMaxDepth = 4; - CdData.MaxDelayedCloseCount = 8; - CdData.MinDelayedCloseCount = 2; - break; - - case MmMediumSystem: - - CdData.IrpContextMaxDepth = 8; - CdData.MaxDelayedCloseCount = 24; - CdData.MinDelayedCloseCount = 6; - break; - - case MmLargeSystem: - - CdData.IrpContextMaxDepth = 32; - CdData.MaxDelayedCloseCount = 72; - CdData.MinDelayedCloseCount = 18; - break; - } - return STATUS_SUCCESS; -} - diff --git a/reactos/drivers/filesystems/cdfs_new/cdprocs.h b/reactos/drivers/filesystems/cdfs_new/cdprocs.h deleted file mode 100755 index 87fcc5a37d4..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/cdprocs.h +++ /dev/null @@ -1,1918 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - CdProcs.h - -Abstract: - - This module defines all of the globally used procedures in the Cdfs - file system. - - ---*/ - -#ifndef _CDPROCS_ -#define _CDPROCS_ - -#include - -#include -#include -#include - -#ifndef INLINE -#define INLINE __inline -#endif - -#include "nodetype.h" -#include "Cd.h" -#include "CdStruc.h" -#include "CdData.h" - - -//**** x86 compiler bug **** - -#if defined(_M_IX86) -#undef Int64ShraMod32 -#define Int64ShraMod32(a, b) ((LONGLONG)(a) >> (b)) -#endif - -// -// Here are the different pool tags. -// - -/* ReactOS Change: GCC doesn't understand this, use TAG macro */ -#include -#define TAG_CCB TAG('c','c','d','C') // Ccb -#define TAG_CDROM_TOC TAG('c','t','d','C') // TOC -#define TAG_DIRENT_NAME TAG('n','d','d','C') // CdName in dirent -#define TAG_ENUM_EXPRESSION TAG('e','e','d','C') // Search expression for enumeration -#define TAG_FCB_DATA TAG('d','f','d','C') // Data Fcb -#define TAG_FCB_INDEX TAG('i','f','d','C') // Index Fcb -#define TAG_FCB_NONPAGED TAG('n','f','d','C') // Nonpaged Fcb -#define TAG_FCB_TABLE TAG('t','f','d','C') // Fcb Table entry -#define TAG_FILE_NAME TAG('n','F','d','C') // Filename buffer -#define TAG_GEN_SHORT_NAME TAG('s','g','d','C') // Generated short name -#define TAG_IO_BUFFER TAG('f','b','d','C') // Temporary IO buffer -#define TAG_IO_CONTEXT TAG('o','i','d','C') // Io context for async reads -#define TAG_IRP_CONTEXT TAG('c','i','d','C') // Irp Context -#define TAG_IRP_CONTEXT_LITE TAG('l','i','d','C') // Irp Context lite -#define TAG_MCB_ARRAY TAG('a','m','d','C') // Mcb array -#define TAG_PATH_ENTRY_NAME TAG('n','P','d','C') // CdName in path entry -#define TAG_PREFIX_ENTRY TAG('e','p','d','C') // Prefix Entry -#define TAG_PREFIX_NAME TAG('n','p','d','C') // Prefix Entry name -#define TAG_SPANNING_PATH_TABLE TAG('p','s','d','C') // Buffer for spanning path table -#define TAG_UPCASE_NAME TAG('n','u','d','C') // Buffer for upcased name -#define TAG_VOL_DESC TAG('d','v','d','C') // Buffer for volume descriptor -#define TAG_VPB TAG('p','v','d','C') // Vpb allocated in filesystem - -// -// Tag all of our allocations if tagging is turned on -// - -#ifdef POOL_TAGGING - -#undef FsRtlAllocatePool -#undef FsRtlAllocatePoolWithQuota -#define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,'sfdC') -#define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,'sfdC') - -#endif // POOL_TAGGING - - -// -// File access check routine, implemented in AcChkSup.c -// - -// -// BOOLEAN -// CdIllegalFcbAccess ( -// IN PIRP_CONTEXT IrpContext, -// IN TYPE_OF_OPEN TypeOfOpen, -// IN ACCESS_MASK DesiredAccess -// ); -// - -#define CdIllegalFcbAccess(IC,T,DA) ( \ - BooleanFlagOn( (DA), \ - ((T) != UserVolumeOpen ? \ - (FILE_WRITE_ATTRIBUTES | \ - FILE_WRITE_DATA | \ - FILE_WRITE_EA | \ - FILE_ADD_FILE | \ - FILE_ADD_SUBDIRECTORY | \ - FILE_APPEND_DATA) : 0) | \ - FILE_DELETE_CHILD | \ - DELETE | \ - WRITE_DAC )) - - -// -// Allocation support routines, implemented in AllocSup.c -// -// These routines are for querying allocation on individual streams. -// - -VOID -CdLookupAllocation ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG FileOffset, - OUT PLONGLONG DiskOffset, - OUT PULONG ByteCount - ); - -VOID -CdAddAllocationFromDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN ULONG McbEntryOffset, - IN LONGLONG StartingFileOffset, - IN PDIRENT Dirent - ); - -VOID -CdAddInitialAllocation ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN ULONG StartingBlock, - IN LONGLONG DataLength - ); - -VOID -CdTruncateAllocation ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG StartingFileOffset - ); - -VOID -CdInitializeMcb ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb - ); - -VOID -CdUninitializeMcb ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb - ); - - -// -// Buffer control routines for data caching, implemented in CacheSup.c -// - -VOID -CdCreateInternalStream ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFCB Fcb - ); - -VOID -CdDeleteInternalStream ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb - ); - -NTSTATUS -CdCompleteMdl ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdPurgeVolume ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN BOOLEAN DismountUnderway - ); - -// -// VOID -// CdUnpinData ( -// IN PIRP_CONTEXT IrpContext, -// IN OUT PBCB *Bcb -// ); -// - -#define CdUnpinData(IC,B) \ - if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; } - - -// -// Device I/O routines, implemented in DevIoSup.c -// -// These routines perform the actual device read and writes. They only affect -// the on disk structure and do not alter any other data structures. -// - -NTSTATUS -CdNonCachedRead ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG StartingOffset, - IN ULONG ByteCount - ); - -NTSTATUS -CdNonCachedXARead ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG StartingOffset, - IN ULONG ByteCount - ); - -BOOLEAN -CdReadSectors ( - IN PIRP_CONTEXT IrpContext, - IN LONGLONG StartingOffset, - IN ULONG ByteCount, - IN BOOLEAN RaiseOnError, - IN OUT PVOID Buffer, - IN PDEVICE_OBJECT TargetDeviceObject - ); - -NTSTATUS -CdCreateUserMdl ( - IN PIRP_CONTEXT IrpContext, - IN ULONG BufferLength, - IN BOOLEAN RaiseOnError - ); - -NTSTATUS -CdPerformDevIoCtrl ( - IN PIRP_CONTEXT IrpContext, - IN ULONG IoControlCode, - IN PDEVICE_OBJECT Device, - OUT PVOID OutputBuffer OPTIONAL, - IN ULONG OutputBufferLength, - IN BOOLEAN InternalDeviceIoControl, - IN BOOLEAN OverrideVerify, - OUT PIO_STATUS_BLOCK Iosb OPTIONAL - ); - -// -// VOID -// CdMapUserBuffer ( -// IN PIRP_CONTEXT IrpContext -// OUT PVOID UserBuffer -// ); -// -// Returns pointer to sys address. Will raise on failure. -// -// -// VOID -// CdLockUserBuffer ( -// IN PIRP_CONTEXT IrpContext, -// IN ULONG BufferLength -// ); -// - -#define CdMapUserBuffer(IC, UB) { \ - *(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ? \ - (IC)->Irp->UserBuffer : \ - (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority))); \ - if (NULL == *(UB)) { \ - CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES); \ - } \ - } - - -#define CdLockUserBuffer(IC,BL) { \ - if ((IC)->Irp->MdlAddress == NULL) { \ - (VOID) CdCreateUserMdl( (IC), (BL), TRUE ); \ - } \ -} - - -// -// Dirent support routines, implemented in DirSup.c -// - -VOID -CdLookupDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN ULONG DirentOffset, - OUT PDIRENT_ENUM_CONTEXT DirContext - ); - -BOOLEAN -CdLookupNextDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PDIRENT_ENUM_CONTEXT CurrentDirContext, - OUT PDIRENT_ENUM_CONTEXT NextDirContext - ); - -VOID -CdUpdateDirentFromRawDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PDIRENT_ENUM_CONTEXT DirContext, - IN OUT PDIRENT Dirent - ); - -VOID -CdUpdateDirentName ( - IN PIRP_CONTEXT IrpContext, - IN OUT PDIRENT Dirent, - IN ULONG IgnoreCase - ); - -BOOLEAN -CdFindFile ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PCD_NAME Name, - IN BOOLEAN IgnoreCase, - IN OUT PFILE_ENUM_CONTEXT FileContext, - OUT PCD_NAME *MatchingName - ); - -BOOLEAN -CdFindDirectory ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PCD_NAME Name, - IN BOOLEAN IgnoreCase, - IN OUT PFILE_ENUM_CONTEXT FileContext - ); - -BOOLEAN -CdFindFileByShortName ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PCD_NAME Name, - IN BOOLEAN IgnoreCase, - IN ULONG ShortNameDirentOffset, - IN OUT PFILE_ENUM_CONTEXT FileContext - ); - -BOOLEAN -CdLookupNextInitialFileDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_ENUM_CONTEXT FileContext - ); - -VOID -CdLookupLastFileDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PFILE_ENUM_CONTEXT FileContext - ); - -VOID -CdCleanupFileContext ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_ENUM_CONTEXT FileContext - ); - -// -// VOID -// CdInitializeFileContext ( -// IN PIRP_CONTEXT IrpContext, -// IN PFILE_ENUM_CONTEXT FileContext -// ); -// -// -// VOID -// CdInitializeDirent ( -// IN PIRP_CONTEXT IrpContext, -// IN PDIRENT Dirent -// ); -// -// VOID -// CdInitializeDirContext ( -// IN PIRP_CONTEXT IrpContext, -// IN PDIRENT_ENUM_CONTEXT DirContext -// ); -// -// VOID -// CdCleanupDirent ( -// IN PIRP_CONTEXT IrpContext, -// IN PDIRENT Dirent -// ); -// -// VOID -// CdCleanupDirContext ( -// IN PIRP_CONTEXT IrpContext, -// IN PDIRENT_ENUM_CONTEXT DirContext -// ); -// -// VOID -// CdLookupInitialFileDirent ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb, -// IN PFILE_ENUM_CONTEXT FileContext, -// IN ULONG DirentOffset -// ); -// - -#define CdInitializeFileContext(IC,FC) { \ - RtlZeroMemory( FC, sizeof( FILE_ENUM_CONTEXT )); \ - (FC)->PriorDirent = &(FC)->Dirents[0]; \ - (FC)->InitialDirent = &(FC)->Dirents[1]; \ - (FC)->CurrentDirent = &(FC)->Dirents[2]; \ - (FC)->ShortName.FileName.MaximumLength = BYTE_COUNT_8_DOT_3; \ - (FC)->ShortName.FileName.Buffer = (FC)->ShortNameBuffer; \ -} - -#define CdInitializeDirent(IC,D) \ - RtlZeroMemory( D, sizeof( DIRENT )) - -#define CdInitializeDirContext(IC,DC) \ - RtlZeroMemory( DC, sizeof( DIRENT_ENUM_CONTEXT )) - -#define CdCleanupDirent(IC,D) { \ - if (FlagOn( (D)->Flags, DIRENT_FLAG_ALLOC_BUFFER )) { \ - CdFreePool( &(D)->CdFileName.FileName.Buffer ); \ - } \ -} - -#define CdCleanupDirContext(IC,DC) \ - CdUnpinData( (IC), &(DC)->Bcb ) - -#define CdLookupInitialFileDirent(IC,F,FC,DO) \ - CdLookupDirent( IC, \ - F, \ - DO, \ - &(FC)->InitialDirent->DirContext ); \ - CdUpdateDirentFromRawDirent( IC, \ - F, \ - &(FC)->InitialDirent->DirContext, \ - &(FC)->InitialDirent->Dirent ) - - -// -// The following routines are used to manipulate the fscontext fields -// of the file object, implemented in FilObSup.c -// - -// -// Type of opens. FilObSup.c depends on this order. -// - -typedef enum _TYPE_OF_OPEN { - - UnopenedFileObject = 0, - StreamFileOpen, - UserVolumeOpen, - UserDirectoryOpen, - UserFileOpen, - BeyondValidType - -} TYPE_OF_OPEN; -typedef TYPE_OF_OPEN *PTYPE_OF_OPEN; - -VOID -CdSetFileObject ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN TYPE_OF_OPEN TypeOfOpen, - IN PFCB Fcb OPTIONAL, - IN PCCB Ccb OPTIONAL - ); - -TYPE_OF_OPEN -CdDecodeFileObject ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - OUT PFCB *Fcb, - OUT PCCB *Ccb - ); - -TYPE_OF_OPEN -CdFastDecodeFileObject ( - IN PFILE_OBJECT FileObject, - OUT PFCB *Fcb - ); - - -// -// Name support routines, implemented in NameSup.c -// - -VOID -CdConvertNameToCdName ( - IN PIRP_CONTEXT IrpContext, - IN OUT PCD_NAME CdName - ); - -VOID -CdConvertBigToLittleEndian ( - IN PIRP_CONTEXT IrpContext, - IN PCHAR BigEndian, - IN ULONG ByteCount, - OUT PCHAR LittleEndian - ); - -VOID -CdUpcaseName ( - IN PIRP_CONTEXT IrpContext, - IN PCD_NAME Name, - IN OUT PCD_NAME UpcaseName - ); - -VOID -CdDissectName ( - IN PIRP_CONTEXT IrpContext, - IN OUT PUNICODE_STRING RemainingName, - OUT PUNICODE_STRING FinalName - ); - -BOOLEAN -CdIs8dot3Name ( - IN PIRP_CONTEXT IrpContext, - IN UNICODE_STRING FileName - ); - -VOID -CdGenerate8dot3Name ( - IN PIRP_CONTEXT IrpContext, - IN PUNICODE_STRING FileName, - IN ULONG DirentOffset, - OUT PWCHAR ShortFileName, - OUT PUSHORT ShortByteCount - ); - -BOOLEAN -CdIsNameInExpression ( - IN PIRP_CONTEXT IrpContext, - IN PCD_NAME CurrentName, - IN PCD_NAME SearchExpression, - IN ULONG WildcardFlags, - IN BOOLEAN CheckVersion - ); - -ULONG -CdShortNameDirentOffset ( - IN PIRP_CONTEXT IrpContext, - IN PUNICODE_STRING Name - ); - -FSRTL_COMPARISON_RESULT -CdFullCompareNames ( - IN PIRP_CONTEXT IrpContext, - IN PUNICODE_STRING NameA, - IN PUNICODE_STRING NameB - ); - - -// -// Filesystem control operations. Implemented in Fsctrl.c -// - -NTSTATUS -CdLockVolumeInternal ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_OBJECT FileObject OPTIONAL - ); - -NTSTATUS -CdUnlockVolumeInternal ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_OBJECT FileObject OPTIONAL - ); - - -// -// Path table enumeration routines. Implemented in PathSup.c -// - -VOID -CdLookupPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN ULONG PathEntryOffset, - IN ULONG Ordinal, - IN BOOLEAN VerifyBounds, - IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry - ); - -BOOLEAN -CdLookupNextPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN OUT PPATH_ENUM_CONTEXT PathContext, - IN OUT PPATH_ENTRY PathEntry - ); - -BOOLEAN -CdFindPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN PFCB ParentFcb, - IN PCD_NAME DirName, - IN BOOLEAN IgnoreCase, - IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry - ); - -VOID -CdUpdatePathEntryName ( - IN PIRP_CONTEXT IrpContext, - IN OUT PPATH_ENTRY PathEntry, - IN BOOLEAN IgnoreCase - ); - -// -// VOID -// CdInitializeCompoundPathEntry ( -// IN PIRP_CONTEXT IrpContext, -// IN PCOMPOUND_PATH_ENTRY CompoundPathEntry -// ); -// -// VOID -// CdCleanupCompoundPathEntry ( -// IN PIRP_CONTEXT IrpContext, -// IN PCOMPOUND_PATH_ENTRY CompoundPathEntry -// ); -// - -#define CdInitializeCompoundPathEntry(IC,CP) \ - RtlZeroMemory( CP, sizeof( COMPOUND_PATH_ENTRY )) - -#define CdCleanupCompoundPathEntry(IC,CP) { \ - CdUnpinData( (IC), &(CP)->PathContext.Bcb ); \ - if ((CP)->PathContext.AllocatedData) { \ - CdFreePool( &(CP)->PathContext.Data ); \ - } \ - if (FlagOn( (CP)->PathEntry.Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )) { \ - CdFreePool( &(CP)->PathEntry.CdDirName.FileName.Buffer ); \ - } \ -} - - -// -// Largest matching prefix searching routines, implemented in PrefxSup.c -// - -VOID -CdInsertPrefix ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PCD_NAME Name, - IN BOOLEAN IgnoreCase, - IN BOOLEAN ShortNameMatch, - IN PFCB ParentFcb - ); - -VOID -CdRemovePrefix ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb - ); - -VOID -CdFindPrefix ( - IN PIRP_CONTEXT IrpContext, - IN OUT PFCB *CurrentFcb, - IN OUT PUNICODE_STRING RemainingName, - IN BOOLEAN IgnoreCase - ); - - -// -// Synchronization routines. Implemented in Resrcsup.c -// -// The following routines/macros are used to synchronize the in-memory structures. -// -// Routine/Macro Synchronizes Subsequent -// -// CdAcquireCdData Volume Mounts/Dismounts,Vcb Queue CdReleaseCdData -// CdAcquireVcbExclusive Vcb for open/close CdReleaseVcb -// CdAcquireVcbShared Vcb for open/close CdReleaseVcb -// CdAcquireAllFiles Locks out operations to all files CdReleaseAllFiles -// CdAcquireFileExclusive Locks out file operations CdReleaseFile -// CdAcquireFileShared Files for file operations CdReleaseFile -// CdAcquireFcbExclusive Fcb for open/close CdReleaseFcb -// CdAcquireFcbShared Fcb for open/close CdReleaseFcb -// CdLockCdData Fields in CdData CdUnlockCdData -// CdLockVcb Vcb fields, FcbReference, FcbTable CdUnlockVcb -// CdLockFcb Fcb fields, prefix table, Mcb CdUnlockFcb -// - -typedef enum _TYPE_OF_ACQUIRE { - - AcquireExclusive, - AcquireShared, - AcquireSharedStarveExclusive - -} TYPE_OF_ACQUIRE, *PTYPE_OF_ACQUIRE; - -BOOLEAN -CdAcquireResource ( - IN PIRP_CONTEXT IrpContext, - IN PERESOURCE Resource, - IN BOOLEAN IgnoreWait, - IN TYPE_OF_ACQUIRE Type - ); - -// -// BOOLEAN -// CdAcquireCdData ( -// IN PIRP_CONTEXT IrpContext -// ); -// -// VOID -// CdReleaseCdData ( -// IN PIRP_CONTEXT IrpContext -// ); -// -// BOOLEAN -// CdAcquireVcbExclusive ( -// IN PIRP_CONTEXT IrpContext, -// IN PVCB Vcb, -// IN BOOLEAN IgnoreWait -// ); -// -// BOOLEAN -// CdAcquireVcbShared ( -// IN PIRP_CONTEXT IrpContext, -// IN PVCB Vcb, -// IN BOOLEAN IgnoreWait -// ); -// -// VOID -// CdReleaseVcb ( -// IN PIRP_CONTEXT IrpContext, -// IN PVCB Vcb -// ); -// -// VOID -// CdAcquireAllFiles ( -// IN PIRP_CONTEXT, -// IN PVCB Vcb -// ); -// -// VOID -// CdReleaseAllFiles ( -// IN PIRP_CONTEXT, -// IN PVCB Vcb -// ); -// -// VOID -// CdAcquireFileExclusive ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb, -// ); -// -// VOID -// CdAcquireFileShared ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// -// VOID -// CdReleaseFile ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// -// BOOLEAN -// CdAcquireFcbExclusive ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb, -// IN BOOLEAN IgnoreWait -// ); -// -// BOOLEAN -// CdAcquireFcbShared ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb, -// IN BOOLEAN IgnoreWait -// ); -// -// BOOLEAN -// CdReleaseFcb ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// -// VOID -// CdLockCdData ( -// ); -// -// VOID -// CdUnlockCdData ( -// ); -// -// VOID -// CdLockVcb ( -// IN PIRP_CONTEXT IrpContext -// ); -// -// VOID -// CdUnlockVcb ( -// IN PIRP_CONTEXT IrpContext -// ); -// -// VOID -// CdLockFcb ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// -// VOID -// CdUnlockFcb ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// - -#define CdAcquireCdData(IC) \ - ExAcquireResourceExclusiveLite( &CdData.DataResource, TRUE ) - -#define CdReleaseCdData(IC) \ - ExReleaseResourceLite( &CdData.DataResource ) - -#define CdAcquireVcbExclusive(IC,V,I) \ - CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive ) - -#define CdAcquireVcbShared(IC,V,I) \ - CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared ) - -#define CdReleaseVcb(IC,V) \ - ExReleaseResourceLite( &(V)->VcbResource ) - -#define CdAcquireAllFiles(IC,V) \ - CdAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive ) - -#define CdReleaseAllFiles(IC,V) \ - ExReleaseResourceLite( &(V)->FileResource ) - -#define CdAcquireFileExclusive(IC,F) \ - CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive ) - -#define CdAcquireFileShared(IC,F) \ - CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared ) - -#define CdAcquireFileSharedStarveExclusive(IC,F) \ - CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive ) - -#define CdReleaseFile(IC,F) \ - ExReleaseResourceLite( (F)->Resource ) - -#define CdAcquireFcbExclusive(IC,F,I) \ - CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive ) - -#define CdAcquireFcbShared(IC,F,I) \ - CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared ) - -#define CdReleaseFcb(IC,F) \ - ExReleaseResourceLite( &(F)->FcbNonpaged->FcbResource ) - -#define CdLockCdData() \ - ExAcquireFastMutex( &CdData.CdDataMutex ); \ - CdData.CdDataLockThread = PsGetCurrentThread() - -#define CdUnlockCdData() \ - CdData.CdDataLockThread = NULL; \ - ExReleaseFastMutex( &CdData.CdDataMutex ) - -#define CdLockVcb(IC,V) \ - ExAcquireFastMutex( &(V)->VcbMutex ); \ - ASSERT( NULL == (V)->VcbLockThread); \ - (V)->VcbLockThread = PsGetCurrentThread() - -#define CdUnlockVcb(IC,V) \ - ASSERT( NULL != (V)->VcbLockThread); \ - (V)->VcbLockThread = NULL; \ - ExReleaseFastMutex( &(V)->VcbMutex ) - -#define CdLockFcb(IC,F) { \ - PVOID _CurrentThread = PsGetCurrentThread(); \ - if (_CurrentThread != (F)->FcbLockThread) { \ - ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex ); \ - ASSERT( (F)->FcbLockCount == 0 ); \ - (F)->FcbLockThread = _CurrentThread; \ - } \ - (F)->FcbLockCount += 1; \ -} - -#define CdUnlockFcb(IC,F) { \ - (F)->FcbLockCount -= 1; \ - if ((F)->FcbLockCount == 0) { \ - (F)->FcbLockThread = NULL; \ - ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex ); \ - } \ -} - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdNoopAcquire ( - IN PVOID Fcb, - IN BOOLEAN Wait - ); - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdNoopRelease ( - IN PVOID Fcb - ); - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdAcquireForCache ( - IN PFCB Fcb, - IN BOOLEAN Wait - ); - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdReleaseFromCache ( - IN PFCB Fcb - ); - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdAcquireForCreateSection ( - IN PFILE_OBJECT FileObject - ); - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdReleaseForCreateSection ( - IN PFILE_OBJECT FileObject - ); - - -// -// In-memory structure support routines. Implemented in StrucSup.c -// - -VOID -CdInitializeVcb ( - IN PIRP_CONTEXT IrpContext, - IN OUT PVCB Vcb, - IN PDEVICE_OBJECT TargetDeviceObject, - IN PVPB Vpb, - IN PCDROM_TOC CdromToc, - IN ULONG TocLength, - IN ULONG TocTrackCount, - IN ULONG TocDiskFlags, - IN ULONG BlockFactor, - IN ULONG MediaChangeCount - ); - -VOID -CdUpdateVcbFromVolDescriptor ( - IN PIRP_CONTEXT IrpContext, - IN OUT PVCB Vcb, - IN PCHAR RawIsoVd OPTIONAL - ); - -VOID -CdDeleteVcb ( - IN PIRP_CONTEXT IrpContext, - IN OUT PVCB Vcb - ); - -PFCB -CdCreateFcb ( - IN PIRP_CONTEXT IrpContext, - IN FILE_ID FileId, - IN NODE_TYPE_CODE NodeTypeCode, - OUT PBOOLEAN FcbExisted OPTIONAL - ); - -VOID -CdInitializeFcbFromPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PFCB ParentFcb OPTIONAL, - IN PPATH_ENTRY PathEntry - ); - -VOID -CdInitializeFcbFromFileContext ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PFCB ParentFcb OPTIONAL, - IN PFILE_ENUM_CONTEXT FileContext - ); - -PCCB -CdCreateCcb ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN ULONG Flags - ); - -VOID -CdDeleteCcb ( - IN PIRP_CONTEXT IrpContext, - IN PCCB Ccb - ); - -BOOLEAN -CdCreateFileLock ( - IN PIRP_CONTEXT IrpContext OPTIONAL, - IN PFCB Fcb, - IN BOOLEAN RaiseOnError - ); - -VOID -CdDeleteFileLock ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_LOCK FileLock - ); - -PIRP_CONTEXT -CdCreateIrpContext ( - IN PIRP Irp, - IN BOOLEAN Wait - ); - -VOID -CdCleanupIrpContext ( - IN PIRP_CONTEXT IrpContext, - IN BOOLEAN Post - ); - -VOID -CdInitializeStackIrpContext ( - OUT PIRP_CONTEXT IrpContext, - IN PIRP_CONTEXT_LITE IrpContextLite - ); - -// -// PIRP_CONTEXT_LITE -// CdCreateIrpContextLite ( -// IN PIRP_CONTEXT IrpContext -// ); -// -// VOID -// CdFreeIrpContextLite ( -// IN PIRP_CONTEXT_LITE IrpContextLite -// ); -// - -#define CdCreateIrpContextLite(IC) \ - ExAllocatePoolWithTag( CdNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE ) - -#define CdFreeIrpContextLite(ICL) \ - CdFreePool( &(ICL) ) - -VOID -CdTeardownStructures ( - IN PIRP_CONTEXT IrpContext, - IN PFCB StartingFcb, - OUT PBOOLEAN RemovedStartingFcb - ); - -// -// VOID -// CdIncrementCleanupCounts ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// -// VOID -// CdDecrementCleanupCounts ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// -// VOID -// CdIncrementReferenceCounts ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb, -// IN ULONG ReferenceCount -// IN ULONG UserReferenceCount -// ); -// -// VOID -// CdDecrementReferenceCounts ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb, -// IN ULONG ReferenceCount -// IN ULONG UserReferenceCount -// ); -// -// VOID -// CdIncrementFcbReference ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// -// VOID -// CdDecrementFcbReference ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// - -#define CdIncrementCleanupCounts(IC,F) { \ - ASSERT_LOCKED_VCB( (F)->Vcb ); \ - (F)->FcbCleanup += 1; \ - (F)->Vcb->VcbCleanup += 1; \ -} - -#define CdDecrementCleanupCounts(IC,F) { \ - ASSERT_LOCKED_VCB( (F)->Vcb ); \ - (F)->FcbCleanup -= 1; \ - (F)->Vcb->VcbCleanup -= 1; \ -} - -#define CdIncrementReferenceCounts(IC,F,C,UC) { \ - ASSERT_LOCKED_VCB( (F)->Vcb ); \ - (F)->FcbReference += (C); \ - (F)->FcbUserReference += (UC); \ - (F)->Vcb->VcbReference += (C); \ - (F)->Vcb->VcbUserReference += (UC); \ -} - -#define CdDecrementReferenceCounts(IC,F,C,UC) { \ - ASSERT_LOCKED_VCB( (F)->Vcb ); \ - (F)->FcbReference -= (C); \ - (F)->FcbUserReference -= (UC); \ - (F)->Vcb->VcbReference -= (C); \ - (F)->Vcb->VcbUserReference -= (UC); \ -} - -// -// PCD_IO_CONTEXT -// CdAllocateIoContext ( -// ); -// -// VOID -// CdFreeIoContext ( -// PCD_IO_CONTEXT IoContext -// ); -// - -#define CdAllocateIoContext() \ - FsRtlAllocatePoolWithTag( CdNonPagedPool, \ - sizeof( CD_IO_CONTEXT ), \ - TAG_IO_CONTEXT ) - -#define CdFreeIoContext(IO) CdFreePool( &(IO) ) - -PFCB -CdLookupFcbTable ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN FILE_ID FileId - ); - -PFCB -CdGetNextFcb ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PVOID *RestartKey - ); - -NTSTATUS -CdProcessToc ( - IN PIRP_CONTEXT IrpContext, - IN PDEVICE_OBJECT TargetDeviceObject, - IN PCDROM_TOC CdromToc, - IN OUT PULONG Length, - OUT PULONG TrackCount, - OUT PULONG DiskFlags - ); - -// -// For debugging purposes we sometimes want to allocate our structures from nonpaged -// pool so that in the kernel debugger we can walk all the structures. -// - -#define CdPagedPool PagedPool -#define CdNonPagedPool NonPagedPool -#define CdNonPagedPoolCacheAligned NonPagedPoolCacheAligned - - -// -// Verification support routines. Contained in verfysup.c -// - -/* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */ -static inline -BOOLEAN -CdOperationIsDasdOpen( - IN PIRP_CONTEXT IrpContext - ) -{ - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->Irp); - - return ((IrpContext->MajorFunction == IRP_MJ_CREATE) && - (IrpSp->FileObject->FileName.Length == 0) && - (IrpSp->FileObject->RelatedFileObject == NULL)); -} - - -NTSTATUS -CdPerformVerify ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PDEVICE_OBJECT DeviceToVerify - ); - -BOOLEAN -CdCheckForDismount ( - IN PIRP_CONTEXT IrpContext, - IN PVCB, - IN BOOLEAN Force - ); - -VOID -CdVerifyVcb ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb - ); - -BOOLEAN -CdVerifyFcbOperation ( - IN PIRP_CONTEXT IrpContext OPTIONAL, - IN PFCB Fcb - ); - -BOOLEAN -CdDismountVcb ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb - ); - - -// -// Macros to abstract device verify flag changes. -// - -#define CdUpdateMediaChangeCount( V, C) (V)->MediaChangeCount = (C) -#define CdUpdateVcbCondition( V, C) (V)->VcbCondition = (C) - -#define CdMarkRealDevForVerify( DO) SetFlag( (DO)->Flags, DO_VERIFY_VOLUME) - -#define CdMarkRealDevVerifyOk( DO) ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME) - - -#define CdRealDevNeedsVerify( DO) BooleanFlagOn( (DO)->Flags, DO_VERIFY_VOLUME) - -// -// BOOLEAN -// CdIsRawDevice ( -// IN PIRP_CONTEXT IrpContext, -// IN NTSTATUS Status -// ); -// - -#define CdIsRawDevice(IC,S) ( \ - ((S) == STATUS_DEVICE_NOT_READY) || \ - ((S) == STATUS_NO_MEDIA_IN_DEVICE) \ -) - - -// -// Work queue routines for posting and retrieving an Irp, implemented in -// workque.c -// - -NTSTATUS -CdFsdPostRequest( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdPrePostIrp ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdOplockComplete ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - - -// -// Miscellaneous support routines -// - -// -// This macro returns TRUE if a flag in a set of flags is on and FALSE -// otherwise -// - -/* ReactOS Change: GCC doesn't understand the comment style */ -/* - //#ifndef BooleanFlagOn -//#define BooleanFlagOn(F,SF) ( \ -// (BOOLEAN)(((F) & (SF)) != 0) \ -//) -//#endif - -//#ifndef SetFlag -//#define SetFlag(Flags,SingleFlag) { \ -// (Flags) |= (SingleFlag); \ -//} -//#endif - -//#ifndef ClearFlag -//#define ClearFlag(Flags,SingleFlag) { \ -// (Flags) &= ~(SingleFlag); \ -//} -//#endif -*/ - -// -// CAST -// Add2Ptr ( -// IN PVOID Pointer, -// IN ULONG Increment -// IN (CAST) -// ); -// -// ULONG -// PtrOffset ( -// IN PVOID BasePtr, -// IN PVOID OffsetPtr -// ); -// - -#define Add2Ptr(PTR,INC,CAST) ((CAST)((PUCHAR)(PTR) + (INC))) - -#define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE))) - -// -// This macro takes a pointer (or ulong) and returns its rounded up word -// value -// - -#define WordAlign(Ptr) ( \ - ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \ - ) - -// -// This macro takes a pointer (or ulong) and returns its rounded up longword -// value -// - -#define LongAlign(Ptr) ( \ - ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \ - ) - -// -// This macro takes a pointer (or ulong) and returns its rounded up quadword -// value -// - -#define QuadAlign(Ptr) ( \ - ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \ - ) - -// -// The following macros round up and down to sector boundaries. -// - -#define SectorAlign(L) ( \ - ((((ULONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \ -) - -#define LlSectorAlign(L) ( \ - ((((LONGLONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \ -) - -#define SectorTruncate(L) ( \ - ((ULONG)(L)) & ~(SECTOR_SIZE - 1) \ -) - -#define LlSectorTruncate(L) ( \ - ((LONGLONG)(L)) & ~(SECTOR_SIZE - 1) \ -) - -#define BytesFromSectors(L) ( \ - ((ULONG) (L)) << SECTOR_SHIFT \ -) - -#define SectorsFromBytes(L) ( \ - ((ULONG) (L)) >> SECTOR_SHIFT \ -) - -#define LlBytesFromSectors(L) ( \ - Int64ShllMod32( (LONGLONG)(L), SECTOR_SHIFT ) \ -) - -#define LlSectorsFromBytes(L) ( \ - Int64ShraMod32( (LONGLONG)(L), SECTOR_SHIFT ) \ -) - -#define SectorOffset(L) ( \ - ((ULONG)(ULONG_PTR) (L)) & SECTOR_MASK \ -) - -#define SectorBlockOffset(V,LB) ( \ - ((ULONG) (LB)) & ((V)->BlocksPerSector - 1) \ -) - -#define BytesFromBlocks(V,B) ( \ - (ULONG) (B) << (V)->BlockToByteShift \ -) - -#define LlBytesFromBlocks(V,B) ( \ - Int64ShllMod32( (LONGLONG) (B), (V)->BlockToByteShift ) \ -) - -#define BlockAlign(V,L) ( \ - ((ULONG)(L) + (V)->BlockMask) & (V)->BlockInverseMask \ -) - -// -// Carefully make sure the mask is sign extended to 64bits -// - -#define LlBlockAlign(V,L) ( \ - ((LONGLONG)(L) + (V)->BlockMask) & (LONGLONG)((LONG)(V)->BlockInverseMask) \ -) - -#define BlockOffset(V,L) ( \ - ((ULONG) (L)) & (V)->BlockMask \ -) - -#define RawSectorAlign( B) ((((B)+(RAW_SECTOR_SIZE - 1)) / RAW_SECTOR_SIZE) * RAW_SECTOR_SIZE) - -// -// The following types and macros are used to help unpack the packed and -// misaligned fields found in the Bios parameter block -// - -typedef union _UCHAR1 { - UCHAR Uchar[1]; - UCHAR ForceAlignment; -} UCHAR1, *PUCHAR1; - -typedef union _UCHAR2 { - UCHAR Uchar[2]; - USHORT ForceAlignment; -} UCHAR2, *PUCHAR2; - -typedef union _UCHAR4 { - UCHAR Uchar[4]; - ULONG ForceAlignment; -} UCHAR4, *PUCHAR4; - -typedef union _USHORT2 { - USHORT Ushort[2]; - ULONG ForceAlignment; -} USHORT2, *PUSHORT2; - -// -// This macro copies an unaligned src byte to an aligned dst byte -// - -#define CopyUchar1(Dst,Src) { \ - *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \ - } - -// -// This macro copies an unaligned src word to an aligned dst word -// - -#define CopyUchar2(Dst,Src) { \ - *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \ - } - -// -// This macro copies an unaligned src longword to an aligned dsr longword -// - -#define CopyUchar4(Dst,Src) { \ - *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \ - } - -// -// This macro copies an unaligned src longword to an aligned dsr longword -// accessing the source on a word boundary. -// - -#define CopyUshort2(Dst,Src) { \ - *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\ - } - - -// -// Following routines handle entry in and out of the filesystem. They are -// contained in CdData.c -// - -NTSTATUS -CdFsdDispatch ( - IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject, - IN PIRP Irp - ); - -LONG -CdExceptionFilter ( - IN PIRP_CONTEXT IrpContext, - IN PEXCEPTION_POINTERS ExceptionPointer - ); - -NTSTATUS -CdProcessException ( - IN PIRP_CONTEXT IrpContext OPTIONAL, - IN PIRP Irp, - IN NTSTATUS ExceptionCode - ); - -VOID -CdCompleteRequest ( - IN PIRP_CONTEXT IrpContext OPTIONAL, - IN PIRP Irp OPTIONAL, - IN NTSTATUS Status - ); - -// -// VOID -// CdRaiseStatus ( -// IN PRIP_CONTEXT IrpContext, -// IN NT_STATUS Status -// ); -// -// VOID -// CdNormalizeAndRaiseStatus ( -// IN PRIP_CONTEXT IrpContext, -// IN NT_STATUS Status -// ); -// - -#if 0 -#define AssertVerifyDevice(C, S) \ - ASSERT( (C) == NULL || \ - FlagOn( (C)->Flags, IRP_CONTEXT_FLAG_IN_FSP ) || \ - !((S) == STATUS_VERIFY_REQUIRED && \ - IoGetDeviceToVerify( PsGetCurrentThread() ) == NULL )); - -#define AssertVerifyDeviceIrp(I) \ - ASSERT( (I) == NULL || \ - !(((I)->IoStatus.Status) == STATUS_VERIFY_REQUIRED && \ - ((I)->Tail.Overlay.Thread == NULL || \ - IoGetDeviceToVerify( (I)->Tail.Overlay.Thread ) == NULL ))); -#else -#define AssertVerifyDevice(C, S) -#define AssertVerifyDeviceIrp(I) -#endif - - -#ifdef CD_SANITY - -DECLSPEC_NORETURN -VOID -CdRaiseStatusEx( - IN PIRP_CONTEXT IrpContext, - IN NTSTATUS Status, - IN BOOLEAN NormalizeStatus, - IN OPTIONAL ULONG FileId, - IN OPTIONAL ULONG Line - ); - -#else - -INLINE -DECLSPEC_NORETURN -VOID -CdRaiseStatusEx( - IN PIRP_CONTEXT IrpContext, - IN NTSTATUS Status, - IN BOOLEAN NormalizeStatus, - IN ULONG Fileid, - IN ULONG Line - ) -{ - if (NormalizeStatus) { - - IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR); - } - else { - - IrpContext->ExceptionStatus = Status; - } - - IrpContext->RaisedAtLineFile = (Fileid << 16) | Line; - - ExRaiseStatus( IrpContext->ExceptionStatus ); -} - -#endif - -#define CdRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), FALSE, BugCheckFileId, __LINE__); -#define CdNormalizeAndRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), TRUE, BugCheckFileId, __LINE__); - -// -// Following are the fast entry points. -// - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastQueryBasicInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, - IN OUT PFILE_BASIC_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ); - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastQueryStdInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, - IN OUT PFILE_STANDARD_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ); - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastLock ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - PEPROCESS ProcessId, - ULONG Key, - BOOLEAN FailImmediately, - BOOLEAN ExclusiveLock, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ); - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastUnlockSingle ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - PEPROCESS ProcessId, - ULONG Key, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ); - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastUnlockAll ( - IN PFILE_OBJECT FileObject, - PEPROCESS ProcessId, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ); - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastUnlockAllByKey ( - IN PFILE_OBJECT FileObject, - PVOID ProcessId, - ULONG Key, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ); - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastIoCheckIfPossible ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - IN BOOLEAN CheckForReadOperation, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ); - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastQueryNetworkInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, - OUT PFILE_NETWORK_OPEN_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ); - -// -// Following are the routines to handle the top level thread logic. -// - -VOID -CdSetThreadContext ( - IN PIRP_CONTEXT IrpContext, - IN PTHREAD_CONTEXT ThreadContext - ); - - -// -// VOID -// CdRestoreThreadContext ( -// IN PIRP_CONTEXT IrpContext -// ); -// - -#define CdRestoreThreadContext(IC) \ - (IC)->ThreadContext->Cdfs = 0; \ - IoSetTopLevelIrp( (IC)->ThreadContext->SavedTopLevelIrp ); \ - (IC)->ThreadContext = NULL - -ULONG -CdSerial32 ( - IN PCHAR Buffer, - IN ULONG ByteCount - ); - -// -// The following macro is used to determine if an FSD thread can block -// for I/O or wait for a resource. It returns TRUE if the thread can -// block and FALSE otherwise. This attribute can then be used to call -// the FSD & FSP common work routine with the proper wait value. -// - -#define CanFsdWait(I) IoIsOperationSynchronous(I) - -// -// The following macro is used to set the fast i/o possible bits in the -// FsRtl header. -// -// FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file. -// -// FastIoIsQuestionable - If there are file locks. -// -// FastIoIsPossible - In all other cases. -// -// - -#define CdIsFastIoPossible(F) ((BOOLEAN) \ - ((((F)->Vcb->VcbCondition != VcbMounted ) || \ - !FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ? \ - \ - FastIoIsNotPossible : \ - \ - ((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \ - \ - FastIoIsQuestionable : \ - \ - FastIoIsPossible)) \ -) - - -// -// The FSP level dispatch/main routine. This is the routine that takes -// IRP's off of the work queue and calls the appropriate FSP level -// work routine. -// - -VOID -CdFspDispatch ( // implemented in FspDisp.c - IN PIRP_CONTEXT IrpContext - ); - -VOID -CdFspClose ( // implemented in Close.c - IN PVCB Vcb OPTIONAL - ); - -// -// The following routines are the entry points for the different operations -// based on the IrpSp major functions. -// - -NTSTATUS -CdCommonCreate ( // Implemented in Create.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonClose ( // Implemented in Close.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonRead ( // Implemented in Read.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonQueryInfo ( // Implemented in FileInfo.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonSetInfo ( // Implemented in FileInfo.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonQueryVolInfo ( // Implemented in VolInfo.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonDirControl ( // Implemented in DirCtrl.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonFsControl ( // Implemented in FsCtrl.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonDevControl ( // Implemented in DevCtrl.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonLockControl ( // Implemented in LockCtrl.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonCleanup ( // Implemented in Cleanup.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdCommonPnp ( // Implemented in Pnp.c - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - - -// -// The following macros are used to establish the semantics needed -// to do a return from within a try-finally clause. As a rule every -// try clause must end with a label call try_exit. For example, -// -// try { -// : -// : -// -// try_exit: NOTHING; -// } finally { -// -// : -// : -// } -// -// Every return statement executed inside of a try clause should use the -// try_return macro. If the compiler fully supports the try-finally construct -// then the macro should be -// -// #define try_return(S) { return(S); } -// -// If the compiler does not support the try-finally construct then the macro -// should be -// -// #define try_return(S) { S; goto try_exit; } -// -/* ReactOS Change: Remove SEH */ -#define try -#define leave goto exitLabel; -#define finally if (0) goto exitLabel; exitLabel: -#define except(x) while (0) -#define GetExceptionCode() 0 -#define AbnormalTermination() 0 - -#define try_return(S) { goto try_exit; } -#define try_leave(S) { leave; } - - -// -// Encapsulate safe pool freeing -// -/* ReactOS Change: GCC "passing argument 1 of CdFreePool from incompatible pointer type" */ -#define CdFreePool(x) _CdFreePool((PVOID*)(x)) - -/* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */ -static inline void _CdFreePool( - IN PVOID *Pool - ) -{ - if (*Pool != NULL) { - - ExFreePool(*Pool); - *Pool = NULL; - } -} - -#endif // _CDPROCS_ - - diff --git a/reactos/drivers/filesystems/cdfs_new/cdstruc.h b/reactos/drivers/filesystems/cdfs_new/cdstruc.h deleted file mode 100755 index d3ffcfd9d40..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/cdstruc.h +++ /dev/null @@ -1,1763 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - CdStruc.h - -Abstract: - - This module defines the data structures that make up the major internal - part of the Cdfs file system. - - In-Memory structures: - - The global data structures with the CdDataRecord. It contains a pointer - to a File System Device object and a queue of Vcb's. There is a Vcb for - every currently or previously mounted volumes. We may be in the process - of tearing down the Vcb's which have been dismounted. The Vcb's are - allocated as an extension to a volume device object. - - +--------+ - | CdData | +--------+ - | | --> |FilSysDo| - | | | | - | | <+ +--------+ - +--------+ | - | - | +--------+ +--------+ - | |VolDo | |VolDo | - | | | | | - | +--------+ +--------+ - +> |Vcb | <-> |Vcb | <-> ... - | | | | - +--------+ +--------+ - - - Each Vcb contains a table of all the Fcbs for the volume indexed by - their FileId. Each Vcb contains a pointer to the root directory of - the volume. Each directory Fcb contains a queue of child Fcb's for - its children. There can also be detached subtrees due to open operations - by Id where the Fcb's are not connected to the root. - - The following diagram shows the root structure. - - +--------+ +--------+ - | Vcb |---->| Fcb |-----------------------------------------------+ - | | | Table |--------------------------------------------+ | | - | |--+ | |-----------------------------------------+ | | | - +--------+ | +--------+ | | | - | | | | | | | - | | | +--------------------+ | | | - | V +---------+ | | | | - | +--------+ | | | | | - | |RootFcb | V V | | | - +->| | +--------+ +--------+ | | | - | |-->|Child | |Child | | | | - +--------+ | Fcb |<-->| Fcb |<--> ... | | | - | | | | | | | - +--------+ +--------+ | | | - | | | - (Freestanding sub-tree) | | | - +--------+ | | | - |OpenById|<-----------------------------------------+ | | - | Dir | +--------+ | | - | |--->|OpenById|<------------------------------+ | - +--------+ | Child | +--------+ | - | Dir |--->|OpenById|<-------------------+ - +--------+ | Child | - | File | - +--------+ - - Attached to each Directory Fcb is a prefix table containing the names - of children of this directory for which there is an Fcb. Not all Fcb's - will necessarily have an entry in this table. - - +--------+ +--------+ - | Dir | | Prefix | - | Fcb |----->| Table |--------------------+ - | | | |-------+ | - +--------+ +--------+ | | - | | | | - | | | | - | V V V - | +--------+ +--------+ +--------+ +--------+ - | | Fcb | | Fcb | | Fcb | | Fcb | - +---------->| |<-->| |<-->| |<-->| | - | | | | | | | | - +--------+ +--------+ +--------+ +--------+ - - - Each file object open on a CDROM volume contains two context pointers. The - first will point back to the Fcb for the file object. The second, if present, - points to a Ccb (ContextControlBlock) which contains the per-handle information. - This includes the state of any directory enumeration. - - +--------+ +--------+ +--------+ - | Fcb |<------| File | | Ccb | - | | | Object|--->| | - | | | | | | - +--------+ +--------+ +--------+ - ^ ^ - | | +--------+ +--------+ - | | | File | | Ccb | - | +---------| Object|--->| | - | | | | | - | +--------+ +--------+ - | - | +--------+ - | |Stream | - +--------------| File | - | Object| - +--------+ - - - Synchronization: - - 1. A resource in the CdData synchronizes access to the Vcb queue. This - is used during mount/verify/dismount operations. - - 2. A resource in the Vcb is used to synchronize access to Vcb for - open/close operations. Typically acquired shared, it - is acquired exclusively to lock out these operations. - - 3. A second resource in the Vcb is used to synchronize all file operations. - Typically acquired shared, it is acquired exclusively to lock - out all file operations. Acquiring both Vcb resources will lock - the entire volume. - - 4. A resource in the nonpaged Fcb will synchronize open/close operations - on an Fcb. - - 5. A fast mutex in the Vcb will protect access to the Fcb table and - the open counts in the Vcb. It is also used to modify the reference - counts in all Fcbs. This mutex cannot be acquired - exclusely and is an end resource. - - 6. A fast mutex in the Fcb will synchronize access to all Fcb fields - which aren't synchronized in some other way. A thread may acquire - mutexes for multiple Fcb's as long as it works it way toward the - root of the tree. This mutex can also be acquired recursively. - - 7. Normal locking order is CdData/Vcb/Fcb starting at any point in this - chain. The Vcb is required prior to acquiring resources for multiple - files. Shared ownership of the Vcb is sufficient in this case. - - 8. Normal locking order when acquiring multiple Fcb's is from some - starting Fcb and walking towards the root of tree. Create typically - walks down the tree. In this case we will attempt to acquire the - next node optimistically and if that fails we will reference - the current node in the tree, release it and acquire the next node. - At that point it will be safe to reacquire the parent node. - - 9. Locking order for the Fcb (via the fast mutex) will be from leaf of - tree back towards the root. No other resource may be acquired - after locking the Vcb (other than in-page reads). - - 10. Cleanup operations only lock the Vcb and Fcb long enough to change the - critical counts and share access fields. No reason to synchronize - otherwise. None of the structures can go away from beneath us - in this case. - - ---*/ - -#ifndef _CDSTRUC_ -#define _CDSTRUC_ - -typedef PVOID PBCB; //**** Bcb's are now part of the cache module - -#define BYTE_COUNT_EMBEDDED_NAME (32) - - -// -// The CD_MCB is used to store the mapping of logical file offset to -// logical disk offset. NOTE - This package only deals with the -// logical 2048 sectors. Translating to 'raw' sectors happens in -// software. We will embed a single MCB_ENTRY in the Fcb since this -// will be the typical case. -// - -typedef struct _CD_MCB { - - // - // Size and current count of the Mcb entries. - // - - ULONG MaximumEntryCount; - ULONG CurrentEntryCount; - - // - // Pointer to the start of the Mcb entries. - // - - struct _CD_MCB_ENTRY *McbArray; - -} CD_MCB; -typedef CD_MCB *PCD_MCB; - -typedef struct _CD_MCB_ENTRY { - - // - // Starting offset and number of bytes described by this entry. - // The Byte count is rounded to a logical block boundary if this is - // the last block. - // - - LONGLONG DiskOffset; - LONGLONG ByteCount; - - // - // Starting offset in the file of mapping described by this dirent. - // - - LONGLONG FileOffset; - - // - // Data length and block length. Data length is the length of each - // data block. Total length is the length of each data block and - // the skip size. - // - - LONGLONG DataBlockByteCount; - LONGLONG TotalBlockByteCount; - -} CD_MCB_ENTRY; -typedef CD_MCB_ENTRY *PCD_MCB_ENTRY; - - -// -// Cd name structure. The following structure is used to represent the -// full Cdrom name. This name can be stored in either Unicode or ANSI -// format. -// - -typedef struct _CD_NAME { - - // - // String containing name without the version number. - // The maximum length field for filename indicates the - // size of the buffer allocated for the two parts of the name. - // - - UNICODE_STRING FileName; - - // - // String containging the version number. - // - - UNICODE_STRING VersionString; - -} CD_NAME; -typedef CD_NAME *PCD_NAME; - -// -// Following is the splay link structure for the prefix lookup. -// The names can be in either Unicode string or Ansi string format. -// - -typedef struct _NAME_LINK { - - RTL_SPLAY_LINKS Links; - UNICODE_STRING FileName; - -} NAME_LINK; -typedef NAME_LINK *PNAME_LINK; - - -// -// Prefix entry. There is one of these for each name in the prefix table. -// An Fcb will have one of these embedded for the long name and an optional -// pointer to the short name entry. -// - -typedef struct _PREFIX_ENTRY { - - // - // Pointer to the Fcb for this entry. - // - - struct _FCB *Fcb; - - // - // Flags field. Used to indicate if the name is in the prefix table. - // - - ULONG PrefixFlags; - - // - // Exact case name match. - // - - NAME_LINK ExactCaseName; - - // - // Case-insensitive name link. - // - - NAME_LINK IgnoreCaseName; - - WCHAR FileNameBuffer[ BYTE_COUNT_EMBEDDED_NAME ]; - -} PREFIX_ENTRY; -typedef PREFIX_ENTRY *PPREFIX_ENTRY; - -#define PREFIX_FLAG_EXACT_CASE_IN_TREE (0x00000001) -#define PREFIX_FLAG_IGNORE_CASE_IN_TREE (0x00000002) - - -// -// The CD_DATA record is the top record in the CDROM file system in-memory -// data structure. This structure must be allocated from non-paged pool. -// - -typedef struct _CD_DATA { - - // - // The type and size of this record (must be CDFS_NTC_DATA_HEADER) - // - - NODE_TYPE_CODE NodeTypeCode; - NODE_BYTE_SIZE NodeByteSize; - - // - // A pointer to the Driver object we were initialized with - // - - PDRIVER_OBJECT DriverObject; - - // - // Vcb queue. - // - - LIST_ENTRY VcbQueue; - - // - // The following fields are used to allocate IRP context structures - // using a lookaside list, and other fixed sized structures from a - // small cache. We use the CdData mutex to protext these structures. - // - - ULONG IrpContextDepth; - ULONG IrpContextMaxDepth; - SINGLE_LIST_ENTRY IrpContextList; - - // - // Filesystem device object for CDFS. - // - - PDEVICE_OBJECT FileSystemDeviceObject; - - // - // Following are used to manage the async and delayed close queue. - // - // FspCloseActive - Indicates whether there is a thread processing the - // two close queues. - // ReduceDelayedClose - Indicates that we have hit the upper threshold - // for the delayed close queue and need to reduce it to lower threshold. - // - // AsyncCloseQueue - Queue of IrpContext waiting for async close operation. - // AsyncCloseCount - Number of entries on the async close queue. - // - // DelayedCloseQueue - Queue of IrpContextLite waiting for delayed close - // operation. - // MaxDelayedCloseCount - Trigger delay close work at this threshold. - // MinDelayedCloseCount - Turn off delay close work at this threshold. - // DelayedCloseCount - Number of entries on the delayted close queue. - // - // CloseItem - Workqueue item used to start FspClose thread. - // - - LIST_ENTRY AsyncCloseQueue; - ULONG AsyncCloseCount; - BOOLEAN FspCloseActive; - BOOLEAN ReduceDelayedClose; - USHORT PadUshort; - - // - // The following fields describe the deferred close file objects. - // - - LIST_ENTRY DelayedCloseQueue; - ULONG DelayedCloseCount; - ULONG MaxDelayedCloseCount; - ULONG MinDelayedCloseCount; - - // - // Fast mutex used to lock the fields of this structure. - // - - PVOID CdDataLockThread; - FAST_MUTEX CdDataMutex; - - // - // A resource variable to control access to the global CDFS data record - // - - ERESOURCE DataResource; - - // - // Cache manager call back structure, which must be passed on each call - // to CcInitializeCacheMap. - // - - CACHE_MANAGER_CALLBACKS CacheManagerCallbacks; - CACHE_MANAGER_CALLBACKS CacheManagerVolumeCallbacks; - - // - // This is the ExWorkerItem that does both kinds of deferred closes. - // - - PIO_WORKITEM CloseItem; - -} CD_DATA; -typedef CD_DATA *PCD_DATA; - - -// -// The Vcb (Volume control block) record corresponds to every -// volume mounted by the file system. They are ordered in a queue off -// of CdData.VcbQueue. -// -// The Vcb will be in several conditions during its lifespan. -// -// NotMounted - Disk is not currently mounted (i.e. removed -// from system) but cleanup and close operations are -// supported. -// -// MountInProgress - State of the Vcb from the time it is -// created until it is successfully mounted or the mount -// fails. -// -// Mounted - Volume is currently in the mounted state. -// -// Invalid - User has invalidated the volume. Only legal operations -// are cleanup and close. -// -// DismountInProgress - We have begun the process of tearing down the -// Vcb. It can be deleted when all the references to it -// have gone away. -// - -typedef enum _VCB_CONDITION { - - VcbNotMounted = 0, - VcbMountInProgress, - VcbMounted, - VcbInvalid, - VcbDismountInProgress - -} VCB_CONDITION; - -typedef struct _VCB { - - // - // The type and size of this record (must be CDFS_NTC_VCB) - // - - NODE_TYPE_CODE NodeTypeCode; - NODE_BYTE_SIZE NodeByteSize; - - // - // Vpb for this volume. - // - - PVPB Vpb; - - // - // Device object for the driver below us. - // - - PDEVICE_OBJECT TargetDeviceObject; - - // - // File object used to lock the volume. - // - - PFILE_OBJECT VolumeLockFileObject; - - // - // Link into queue of Vcb's in the CdData structure. We will create a union with - // a LONGLONG to force the Vcb to be quad-aligned. - // - - union { - - LIST_ENTRY VcbLinks; - LONGLONG Alignment; - }; - - // - // State flags and condition for the Vcb. - // - - ULONG VcbState; - VCB_CONDITION VcbCondition; - - // - // Various counts for this Vcb. - // - // VcbCleanup - Open handles left on this system. - // VcbReference - Number of reasons this Vcb is still present. - // VcbUserReference - Number of user file objects still present. - // - - ULONG VcbCleanup; - LONG VcbReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */ - LONG VcbUserReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */ - - // - // Fcb for the Volume Dasd file, root directory and the Path Table. - // - - struct _FCB *VolumeDasdFcb; - struct _FCB *RootIndexFcb; - struct _FCB *PathTableFcb; - - // - // Location of current session and offset of volume descriptors. - // - - ULONG BaseSector; - ULONG VdSectorOffset; - ULONG PrimaryVdSectorOffset; - - // - // Following is a sector from the last non-cached read of an XA file. - // Also the cooked offset on the disk. - // - - PVOID XASector; - LONGLONG XADiskOffset; - - // - // Vcb resource. This is used to synchronize open/cleanup/close operations. - // - - ERESOURCE VcbResource; - - // - // File resource. This is used to synchronize all file operations except - // open/cleanup/close. - // - - ERESOURCE FileResource; - - // - // Vcb fast mutex. This is used to synchronize the fields in the Vcb - // when modified when the Vcb is not held exclusively. Included here - // are the count fields and Fcb table. - // - // We also use this to synchronize changes to the Fcb reference field. - // - - FAST_MUTEX VcbMutex; - PVOID VcbLockThread; - - // - // The following is used to synchronize the dir notify package. - // - - PNOTIFY_SYNC NotifySync; - - // - // The following is the head of a list of notify Irps. - // - - LIST_ENTRY DirNotifyList; - - // - // Logical block size for this volume as well constant values - // associated with the block size. - // - - ULONG BlockSize; - ULONG BlockToSectorShift; - ULONG BlockToByteShift; - ULONG BlocksPerSector; - ULONG BlockMask; - ULONG BlockInverseMask; - - // - // Fcb table. Synchronized with the Vcb fast mutex. - // - - RTL_GENERIC_TABLE FcbTable; - - // - // Volume TOC. Cache this information for quick lookup. - // - - PCDROM_TOC CdromToc; - ULONG TocLength; - ULONG TrackCount; - ULONG DiskFlags; - - // - // Block factor to determine last session information. - // - - ULONG BlockFactor; - - // - // Media change count from device driver for bulletproof detection - // of media movement - // - - ULONG MediaChangeCount; - - // - // For raw reads, CDFS must obey the port maximum transfer restrictions. - // - - ULONG MaximumTransferRawSectors; - ULONG MaximumPhysicalPages; - - // - // Preallocated VPB for swapout, so we are not forced to consider - // must succeed pool. - // - - PVPB SwapVpb; - -} VCB; -typedef VCB *PVCB; - -#define VCB_STATE_HSG (0x00000001) -#define VCB_STATE_ISO (0x00000002) -#define VCB_STATE_JOLIET (0x00000004) -#define VCB_STATE_LOCKED (0x00000010) -#define VCB_STATE_REMOVABLE_MEDIA (0x00000020) -#define VCB_STATE_CDXA (0x00000040) -#define VCB_STATE_AUDIO_DISK (0x00000080) -#define VCB_STATE_NOTIFY_REMOUNT (0x00000100) -#define VCB_STATE_VPB_NOT_ON_DEVICE (0x00000200) - - -// -// The Volume Device Object is an I/O system device object with a -// workqueue and an VCB record appended to the end. There are multiple -// of these records, one for every mounted volume, and are created during -// a volume mount operation. The work queue is for handling an overload -// of work requests to the volume. -// - -typedef struct _VOLUME_DEVICE_OBJECT { - - DEVICE_OBJECT DeviceObject; - - // - // The following field tells how many requests for this volume have - // either been enqueued to ExWorker threads or are currently being - // serviced by ExWorker threads. If the number goes above - // a certain threshold, put the request on the overflow queue to be - // executed later. - // - - LONG PostedRequestCount; /* ReactOS Change: GCC "pointer targets in passing argument 1 of 'InterlockedDecrement' differ in signedness" */ - - // - // The following field indicates the number of IRP's waiting - // to be serviced in the overflow queue. - // - - ULONG OverflowQueueCount; - - // - // The following field contains the queue header of the overflow queue. - // The Overflow queue is a list of IRP's linked via the IRP's ListEntry - // field. - // - - LIST_ENTRY OverflowQueue; - - // - // The following spinlock protects access to all the above fields. - // - - KSPIN_LOCK OverflowQueueSpinLock; - - // - // This is the file system specific volume control block. - // - - VCB Vcb; - -} VOLUME_DEVICE_OBJECT; -typedef VOLUME_DEVICE_OBJECT *PVOLUME_DEVICE_OBJECT; - - -// -// The following two structures are the separate union structures for -// data and index Fcb's. The path table is actually the same structure -// as the index Fcb since it uses the first few fields. -// - -typedef enum _FCB_CONDITION { - FcbGood = 1, - FcbBad, - FcbNeedsToBeVerified -} FCB_CONDITION; - -typedef struct _FCB_DATA { - - // - // The following field is used by the oplock module - // to maintain current oplock information. - // - - OPLOCK Oplock; - - // - // The following field is used by the filelock module - // to maintain current byte range locking information. - // A file lock is allocated as needed. - // - - PFILE_LOCK FileLock; - -} FCB_DATA; -typedef FCB_DATA *PFCB_DATA; - -typedef struct _FCB_INDEX { - - // - // Internal stream file. - // - - PFILE_OBJECT FileObject; - - // - // Offset of first entry in stream. This is for case where directory - // or path table does not begin on a sector boundary. This value is - // added to all offset values to determine the real offset. - // - - ULONG StreamOffset; - - // - // List of child fcbs. - // - - LIST_ENTRY FcbQueue; - - // - // Ordinal number for this directory. Combine this with the path table offset - // in the FileId and you have a starting point in the path table. - // - - ULONG Ordinal; - - // - // Children path table start. This is the offset in the path table - // for the first child of the directory. A value of zero indicates - // that we haven't found the first child yet. If there are no child - // directories we will position at a point in the path table so that - // subsequent searches will fail quickly. - // - - ULONG ChildPathTableOffset; - ULONG ChildOrdinal; - - // - // Root of splay trees for exact and ignore case prefix trees. - // - - PRTL_SPLAY_LINKS ExactCaseRoot; - PRTL_SPLAY_LINKS IgnoreCaseRoot; - -} FCB_INDEX; -typedef FCB_INDEX *PFCB_INDEX; - -typedef struct _FCB_NONPAGED { - - // - // Type and size of this record must be CDFS_NTC_FCB_NONPAGED - // - - NODE_TYPE_CODE NodeTypeCode; - NODE_BYTE_SIZE NodeByteSize; - - // - // The following field contains a record of special pointers used by - // MM and Cache to manipluate section objects. Note that the values - // are set outside of the file system. However the file system on an - // open/create will set the file object's SectionObject field to - // point to this field - // - - SECTION_OBJECT_POINTERS SegmentObject; - - // - // This is the resource structure for this Fcb. - // - - ERESOURCE FcbResource; - - // - // This is the FastMutex for this Fcb. - // - - FAST_MUTEX FcbMutex; - - // - // This is the mutex that is inserted into the FCB_ADVANCED_HEADER - // FastMutex field - // - - FAST_MUTEX AdvancedFcbHeaderMutex; - -} FCB_NONPAGED; -typedef FCB_NONPAGED *PFCB_NONPAGED; - -// -// The Fcb/Dcb record corresponds to every open file and directory, and to -// every directory on an opened path. -// - -typedef struct _FCB { - - // - // The following field is used for fast I/O. It contains the node - // type code and size, indicates if fast I/O is possible, contains - // allocation, file, and valid data size, a resource, and call back - // pointers for FastIoRead and FastMdlRead. - // - // - // Node type codes for the Fcb must be one of the following. - // - // CDFS_NTC_FCB_PATH_TABLE - // CDFS_NTC_FCB_INDEX - // CDFS_NTC_FCB_DATA - // - - // - // Common Fsrtl Header. The named header is for the fieldoff.c output. We - // use the unnamed header internally. - // - - union{ - - FSRTL_ADVANCED_FCB_HEADER Header; - FSRTL_ADVANCED_FCB_HEADER; - }; - - // - // Vcb for this Fcb. - // - - PVCB Vcb; - - // - // Parent Fcb for this Fcb. This may be NULL if this file was opened - // by ID, also for the root Fcb. - // - - struct _FCB *ParentFcb; - - // - // Links to the queue of Fcb's in the parent. - // - - LIST_ENTRY FcbLinks; - - // - // FileId for this file. - // - - FILE_ID FileId; - - // - // Counts on this Fcb. Cleanup count represents the number of open handles - // on this Fcb. Reference count represents the number of reasons this Fcb - // is still present. It includes file objects, children Fcb and anyone - // who wants to prevent this Fcb from going away. Cleanup count is synchronized - // with the FcbResource. The reference count is synchronized with the - // VcbMutex. - // - - ULONG FcbCleanup; - LONG FcbReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */ - ULONG FcbUserReference; - - // - // State flags for this Fcb. - // - - ULONG FcbState; - - // - // NT style attributes for the Fcb. - // - - ULONG FileAttributes; - - // - // CDXA attributes for this file. - // - - USHORT XAAttributes; - - // - // File number from the system use area. - // - - UCHAR XAFileNumber; - - // - // This is the thread and count for the thread which has locked this - // Fcb. - // - - PVOID FcbLockThread; - ULONG FcbLockCount; - - // - // Pointer to the Fcb non-paged structures. - // - - PFCB_NONPAGED FcbNonpaged; - - // - // Share access structure. - // - - SHARE_ACCESS ShareAccess; - - // - // Mcb for the on disk mapping and a single map entry. - // - - CD_MCB_ENTRY McbEntry; - CD_MCB Mcb; - - // - // Embed the prefix entry for the longname. Store an optional pointer - // to a prefix structure for the short name. - // - - PPREFIX_ENTRY ShortNamePrefix; - PREFIX_ENTRY FileNamePrefix; - - // - // Time stamp for this file. - // - - LONGLONG CreationTime; - - union{ - - ULONG FcbType; - FCB_DATA; - FCB_INDEX; - }; - -} FCB; -typedef FCB *PFCB; - -#define FCB_STATE_INITIALIZED (0x00000001) -#define FCB_STATE_IN_FCB_TABLE (0x00000002) -#define FCB_STATE_MODE2FORM2_FILE (0x00000004) -#define FCB_STATE_MODE2_FILE (0x00000008) -#define FCB_STATE_DA_FILE (0x00000010) - -// -// These file types are read as raw 2352 byte sectors -// - -#define FCB_STATE_RAWSECTOR_MASK ( FCB_STATE_MODE2FORM2_FILE | \ - FCB_STATE_MODE2_FILE | \ - FCB_STATE_DA_FILE ) - -#define SIZEOF_FCB_DATA \ - (FIELD_OFFSET( FCB, FcbType ) + sizeof( FCB_DATA )) - -#define SIZEOF_FCB_INDEX \ - (FIELD_OFFSET( FCB, FcbType ) + sizeof( FCB_INDEX )) - - -// -// The Ccb record is allocated for every file object -// - -typedef struct _CCB { - - // - // Type and size of this record (must be CDFS_NTC_CCB) - // - - NODE_TYPE_CODE NodeTypeCode; - NODE_BYTE_SIZE NodeByteSize; - - // - // Flags. Indicates flags to apply for the current open. - // - - ULONG Flags; - - // - // Fcb for the file being opened. - // - - PFCB Fcb; - - // - // We store state information in the Ccb for a directory - // enumeration on this handle. - // - - // - // Offset in the directory stream to base the next enumeration. - // - - ULONG CurrentDirentOffset; - CD_NAME SearchExpression; - -} CCB; -typedef CCB *PCCB; - -#define CCB_FLAG_OPEN_BY_ID (0x00000001) -#define CCB_FLAG_OPEN_RELATIVE_BY_ID (0x00000002) -#define CCB_FLAG_IGNORE_CASE (0x00000004) -#define CCB_FLAG_OPEN_WITH_VERSION (0x00000008) -#define CCB_FLAG_DISMOUNT_ON_CLOSE (0x00000010) - -// -// Following flags refer to index enumeration. -// - -#define CCB_FLAG_ENUM_NAME_EXP_HAS_WILD (0x00010000) -#define CCB_FLAG_ENUM_VERSION_EXP_HAS_WILD (0x00020000) -#define CCB_FLAG_ENUM_MATCH_ALL (0x00040000) -#define CCB_FLAG_ENUM_VERSION_MATCH_ALL (0x00080000) -#define CCB_FLAG_ENUM_RETURN_NEXT (0x00100000) -#define CCB_FLAG_ENUM_INITIALIZED (0x00200000) -#define CCB_FLAG_ENUM_NOMATCH_CONSTANT_ENTRY (0x00400000) - - -// -// The Irp Context record is allocated for every orginating Irp. It is -// created by the Fsd dispatch routines, and deallocated by the CdComplete -// request routine -// - -typedef struct _IRP_CONTEXT { - - // - // Type and size of this record (must be CDFS_NTC_IRP_CONTEXT) - // - - NODE_TYPE_CODE NodeTypeCode; - NODE_BYTE_SIZE NodeByteSize; - - // - // Originating Irp for the request. - // - - PIRP Irp; - - // - // Vcb for this operation. When this is NULL it means we were called - // with our filesystem device object instead of a volume device object. - // (Mount will fill this in once the Vcb is created) - // - - PVCB Vcb; - - // - // Exception encountered during the request. Any error raised explicitly by - // the file system will be stored here. Any other error raised by the system - // is stored here after normalizing it. - // - - NTSTATUS ExceptionStatus; - ULONG RaisedAtLineFile; - - // - // Flags for this request. - // - - ULONG Flags; - - // - // Real device object. This represents the physical device closest to the media. - // - - PDEVICE_OBJECT RealDevice; - - // - // Io context for a read request. - // Address of Fcb for teardown oplock in create case. - // - - union { - - struct _CD_IO_CONTEXT *IoContext; - PFCB *TeardownFcb; - }; - - // - // Top level irp context for this thread. - // - - struct _IRP_CONTEXT *TopLevel; - - // - // Major and minor function codes. - // - - UCHAR MajorFunction; - UCHAR MinorFunction; - - // - // Pointer to the top-level context if this IrpContext is responsible - // for cleaning it up. - // - - struct _THREAD_CONTEXT *ThreadContext; - - // - // This structure is used for posting to the Ex worker threads. - // - - WORK_QUEUE_ITEM WorkQueueItem; - -} IRP_CONTEXT; -typedef IRP_CONTEXT *PIRP_CONTEXT; - -#define IRP_CONTEXT_FLAG_ON_STACK (0x00000001) -#define IRP_CONTEXT_FLAG_MORE_PROCESSING (0x00000002) -#define IRP_CONTEXT_FLAG_WAIT (0x00000004) -#define IRP_CONTEXT_FLAG_FORCE_POST (0x00000008) -#define IRP_CONTEXT_FLAG_TOP_LEVEL (0x00000010) -#define IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS (0x00000020) -#define IRP_CONTEXT_FLAG_IN_FSP (0x00000040) -#define IRP_CONTEXT_FLAG_IN_TEARDOWN (0x00000080) -#define IRP_CONTEXT_FLAG_ALLOC_IO (0x00000100) -#define IRP_CONTEXT_FLAG_DISABLE_POPUPS (0x00000200) -#define IRP_CONTEXT_FLAG_FORCE_VERIFY (0x00000400) - -// -// Flags used for create. -// - -#define IRP_CONTEXT_FLAG_FULL_NAME (0x10000000) -#define IRP_CONTEXT_FLAG_TRAIL_BACKSLASH (0x20000000) - -// -// The following flags need to be cleared when a request is posted. -// - -#define IRP_CONTEXT_FLAGS_CLEAR_ON_POST ( \ - IRP_CONTEXT_FLAG_MORE_PROCESSING | \ - IRP_CONTEXT_FLAG_WAIT | \ - IRP_CONTEXT_FLAG_FORCE_POST | \ - IRP_CONTEXT_FLAG_TOP_LEVEL | \ - IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS | \ - IRP_CONTEXT_FLAG_IN_FSP | \ - IRP_CONTEXT_FLAG_IN_TEARDOWN | \ - IRP_CONTEXT_FLAG_DISABLE_POPUPS \ -) - -// -// The following flags need to be cleared when a request is retried. -// - -#define IRP_CONTEXT_FLAGS_CLEAR_ON_RETRY ( \ - IRP_CONTEXT_FLAG_MORE_PROCESSING | \ - IRP_CONTEXT_FLAG_IN_TEARDOWN | \ - IRP_CONTEXT_FLAG_DISABLE_POPUPS \ -) - -// -// The following flags are set each time through the Fsp loop. -// - -#define IRP_CONTEXT_FSP_FLAGS ( \ - IRP_CONTEXT_FLAG_WAIT | \ - IRP_CONTEXT_FLAG_TOP_LEVEL | \ - IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS | \ - IRP_CONTEXT_FLAG_IN_FSP \ -) - - -// -// Following structure is used to queue a request to the delayed close queue. -// This structure should be the minimum block allocation size. -// - -typedef struct _IRP_CONTEXT_LITE { - - // - // Type and size of this record (must be CDFS_NTC_IRP_CONTEXT_LITE) - // - - NODE_TYPE_CODE NodeTypeCode; - NODE_BYTE_SIZE NodeByteSize; - - // - // Fcb for the file object being closed. - // - - PFCB Fcb; - - // - // List entry to attach to delayed close queue. - // - - LIST_ENTRY DelayedCloseLinks; - - // - // User reference count for the file object being closed. - // - - ULONG UserReference; - - // - // Real device object. This represents the physical device closest to the media. - // - - PDEVICE_OBJECT RealDevice; - -} IRP_CONTEXT_LITE; -typedef IRP_CONTEXT_LITE *PIRP_CONTEXT_LITE; - - -// -// Context structure for asynchronous I/O calls. Most of these fields -// are actually only required for the ReadMultiple routines, but -// the caller must allocate one as a local variable anyway before knowing -// whether there are multiple requests are not. Therefore, a single -// structure is used for simplicity. -// - -typedef struct _CD_IO_CONTEXT { - - // - // These two fields are used for multiple run Io - // - - LONG IrpCount; - PIRP MasterIrp; - NTSTATUS Status; - BOOLEAN AllocatedContext; - - union { - - // - // This element handles the asynchronous non-cached Io - // - - struct { - - PERESOURCE Resource; - ERESOURCE_THREAD ResourceThreadId; - ULONG RequestedByteCount; - }; - - // - // and this element handles the synchronous non-cached Io. - // - - KEVENT SyncEvent; - }; - -} CD_IO_CONTEXT; -typedef CD_IO_CONTEXT *PCD_IO_CONTEXT; - - -// -// Following structure is used to track the top level request. Each Cdfs -// Fsd and Fsp entry point will examine the top level irp location in the -// thread local storage to determine if this request is top level and/or -// top level Cdfs. The top level Cdfs request will remember the previous -// value and update that location with a stack location. This location -// can be accessed by recursive Cdfs entry points. -// - -typedef struct _THREAD_CONTEXT { - - // - // CDFS signature. Used to confirm structure on stack is valid. - // - - ULONG Cdfs; - - // - // Previous value in top-level thread location. We restore this - // when done. - // - - PIRP SavedTopLevelIrp; - - // - // Top level Cdfs IrpContext. Initial Cdfs entry point on stack - // will store the IrpContext for the request in this stack location. - // - - PIRP_CONTEXT TopLevelIrpContext; - -} THREAD_CONTEXT; -typedef THREAD_CONTEXT *PTHREAD_CONTEXT; - - -// -// The following structure is used for enumerating the entries in the -// path table. We will always map this two sectors at a time so we don't -// have to worry about entries which span sectors. We move through -// one sector at a time though. We will unpin and remap after -// crossing a sector boundary. -// -// The only special case is where we span a cache view. In that case -// we will allocate a buffer and read both pieces into it. -// -// This strategy takes advantage of the CC enhancement which allows -// overlapping ranges. -// - -typedef struct _PATH_ENUM_CONTEXT { - - // - // Pointer to the current sector and the offset of this sector to - // the beginning of the path table. The Data pointer may be - // a pool block in the case where we cross a cache view - // boundary. Also the length of the data for this block. - // - - PVOID Data; - ULONG BaseOffset; - ULONG DataLength; - - // - // Bcb for the sector. (We may actually have pinned two sectors) - // This will be NULL for the case where we needed to allocate a - // buffer in the case where we span a cache view. - // - - PBCB Bcb; - - // - // Offset to current entry within the current data block. - // - - ULONG DataOffset; - - // - // Did we allocate the buffer for the entry. - // - - BOOLEAN AllocatedData; - - // - // End of Path Table. This tells us whether the current data - // block includes the end of the path table. This is the - // only block where we need to do a careful check about whether - // the path table entry fits into the buffer. - // - // Also once we have reached the end of the path table we don't - // need to remap the data as we move into the final sector. - // We always look at the last two sectors together. - // - - BOOLEAN LastDataBlock; - -} PATH_ENUM_CONTEXT; -typedef PATH_ENUM_CONTEXT *PPATH_ENUM_CONTEXT; - -#define VACB_MAPPING_MASK (VACB_MAPPING_GRANULARITY - 1) -#define LAST_VACB_SECTOR_OFFSET (VACB_MAPPING_GRANULARITY - SECTOR_SIZE) - - -// -// Path Entry. This is our representation of the on disk data. -// - -typedef struct _PATH_ENTRY { - - // - // Directory number and offset. This is the ordinal and the offset from - // the beginning of the path table stream for this entry. - // - // - - ULONG Ordinal; - ULONG PathTableOffset; - - // - // Logical block Offset on the disk for this entry. We already bias - // this by any Xar blocks. - // - - ULONG DiskOffset; - - // - // Length of on-disk path table entry. - // - - ULONG PathEntryLength; - - // - // Parent number. - // - - ULONG ParentOrdinal; - - // - // DirName length and Id. Typically the pointer here points to the raw on-disk - // bytes. We will point to a fixed self entry if this is the root directory. - // - - ULONG DirNameLen; - PCHAR DirName; - - // - // Following are the flags used to cleanup this structure. - // - - ULONG Flags; - - // - // The following is the filename string and version number strings. We embed a buffer - // large enough to hold two 8.3 names. One for exact case and one for case insensitive. - // - - CD_NAME CdDirName; - CD_NAME CdCaseDirName; - - WCHAR NameBuffer[BYTE_COUNT_EMBEDDED_NAME / sizeof( WCHAR ) * 2]; - -} PATH_ENTRY; -typedef PATH_ENTRY *PPATH_ENTRY; - -#define PATH_ENTRY_FLAG_ALLOC_BUFFER (0x00000001) - - -// -// Compound path entry. This structure combines the on-disk entries -// with the in-memory structures. -// - -typedef struct _COMPOUND_PATH_ENTRY { - - PATH_ENUM_CONTEXT PathContext; - PATH_ENTRY PathEntry; - -} COMPOUND_PATH_ENTRY; -typedef COMPOUND_PATH_ENTRY *PCOMPOUND_PATH_ENTRY; - - -// -// The following is used for enumerating through a directory via the -// dirents. -// - -typedef struct _DIRENT_ENUM_CONTEXT { - - // - // Pointer the current sector and the offset of this sector within - // the directory file. Also the data length of this pinned block. - // - - PVOID Sector; - ULONG BaseOffset; - ULONG DataLength; - - // - // Bcb for the sector. - // - - PBCB Bcb; - - // - // Offset to the current dirent within this sector. - // - - ULONG SectorOffset; - - // - // Length to next dirent. A zero indicates to move to the next sector. - // - - ULONG NextDirentOffset; - -} DIRENT_ENUM_CONTEXT; -typedef DIRENT_ENUM_CONTEXT *PDIRENT_ENUM_CONTEXT; - - -// -// Following structure is used to smooth out the differences in the HSG, ISO -// and Joliett directory entries. -// - -typedef struct _DIRENT { - - // - // Offset in the Directory of this entry. Note this includes - // any bytes added to the beginning of the directory to pad - // down to a sector boundary. - // - - ULONG DirentOffset; - - ULONG DirentLength; - - // - // Starting offset on the disk including any Xar blocks. - // - - ULONG StartingOffset; - - // - // DataLength of the data. If not the last block then this should - // be an integral number of logical blocks. - // - - ULONG DataLength; - - // - // The following field is the time stamp out of the directory entry. - // Use a pointer into the dirent for this. - // - - PCHAR CdTime; - - // - // The following field is the dirent file flags field. - // - - UCHAR DirentFlags; - - // - // Following field is a Cdfs flag field used to clean up this structure. - // - - UCHAR Flags; - - // - // The following fields indicate the file unit size and interleave gap - // for interleaved files. Each of these are in logical blocks. - // - - ULONG FileUnitSize; - ULONG InterleaveGapSize; - - // - // System use offset. Zero value indicates no system use area. - // - - ULONG SystemUseOffset; - - // - // CDXA attributes and file number for this file. - // - - USHORT XAAttributes; - UCHAR XAFileNumber; - - // - // Filename length and ID. We copy the length (in bytes) and keep - // a pointer to the start of the name. - // - - ULONG FileNameLen; - PCHAR FileName; - - // - // The following are the filenames stored by name and version numbers. - // The fixed buffer here can hold two Unicode 8.3 names. This allows - // us to upcase the name into a fixed buffer. - // - - CD_NAME CdFileName; - CD_NAME CdCaseFileName; - - // - // Data stream type. Indicates if this is audio, XA mode2 form2 or cooked sectors. - // - - XA_EXTENT_TYPE ExtentType; - - WCHAR NameBuffer[BYTE_COUNT_EMBEDDED_NAME / sizeof( WCHAR ) * 2]; - -} DIRENT; -typedef DIRENT *PDIRENT; - -#define DIRENT_FLAG_ALLOC_BUFFER (0x01) -#define DIRENT_FLAG_CONSTANT_ENTRY (0x02) - -#define DIRENT_FLAG_NOT_PERSISTENT (0) - - -// -// Following structure combines the on-disk information with the normalized -// structure. -// - -typedef struct _COMPOUND_DIRENT { - - DIRENT_ENUM_CONTEXT DirContext; - DIRENT Dirent; - -} COMPOUND_DIRENT; -typedef COMPOUND_DIRENT *PCOMPOUND_DIRENT; - - -// -// The following structure is used to enumerate the files in a directory. -// It contains three DirContext/Dirent pairs and then self pointers to -// know which of these is begin used how. -// - -typedef struct _FILE_ENUM_CONTEXT { - - // - // Pointers to the current compound dirents below. - // - // PriorDirent - Initial dirent for the last file encountered. - // InitialDirent - Initial dirent for the current file. - // CurrentDirent - Second or later dirent for the current file. - // - - PCOMPOUND_DIRENT PriorDirent; - PCOMPOUND_DIRENT InitialDirent; - PCOMPOUND_DIRENT CurrentDirent; - - // - // Flags indicating the state of the search. - // - - ULONG Flags; - - // - // This is an accumulation of the file sizes of the different extents - // of a single file. - // - - LONGLONG FileSize; - - // - // Short name for this file. - // - - CD_NAME ShortName; - WCHAR ShortNameBuffer[ BYTE_COUNT_8_DOT_3 / sizeof( WCHAR ) ]; - - // - // Array of compound dirents. - // - - COMPOUND_DIRENT Dirents[3]; - -} FILE_ENUM_CONTEXT; -typedef FILE_ENUM_CONTEXT *PFILE_ENUM_CONTEXT; - -#define FILE_CONTEXT_MULTIPLE_DIRENTS (0x00000001) - - -// -// RIFF header. Prepended to the data of a file containing XA sectors. -// This is a hard-coded structure except that we bias the 'ChunkSize' and -// 'RawSectors' fields with the file size. We also copy the attributes flag -// from the system use area in the dirent. We always initialize this -// structure by copying the XAFileHeader. -// - -typedef struct _RIFF_HEADER { - - ULONG ChunkId; - LONG ChunkSize; - ULONG SignatureCDXA; - ULONG SignatureFMT; - ULONG XAChunkSize; - ULONG OwnerId; - USHORT Attributes; - USHORT SignatureXA; - UCHAR FileNumber; - UCHAR Reserved[7]; - ULONG SignatureData; - ULONG RawSectors; - -} RIFF_HEADER; -typedef RIFF_HEADER *PRIFF_HEADER; - -// -// Audio play header for CDDA tracks. -// - -typedef struct _AUDIO_PLAY_HEADER { - - ULONG Chunk; - ULONG ChunkSize; - ULONG SignatureCDDA; - ULONG SignatureFMT; - ULONG FMTChunkSize; - USHORT FormatTag; - USHORT TrackNumber; - ULONG DiskID; - ULONG StartingSector; - ULONG SectorCount; - UCHAR TrackAddress[4]; - UCHAR TrackLength[4]; - -} AUDIO_PLAY_HEADER; -typedef AUDIO_PLAY_HEADER *PAUDIO_PLAY_HEADER; - - -// -// Some macros for supporting the use of a Generic Table -// containing all the FCB/DCBs and indexed by their FileId. -// -// For directories: -// -// The HighPart contains the path table offset of this directory in the -// path table. -// -// The LowPart contains zero except for the upper bit which is -// set to indicate that this is a directory. -// -// For files: -// -// The HighPart contains the path table offset of the parent directory -// in the path table. -// -// The LowPart contains the byte offset of the dirent in the parent -// directory file. -// -// A directory is always entered into the Fcb Table as if it's -// dirent offset was zero. This enables any child to look in the FcbTable -// for it's parent by searching with the same HighPart but with zero -// as the value for LowPart. -// -// The Id field is a LARGE_INTEGER where the High and Low parts can be -// accessed separately. -// -// The following macros are used to access the Fid fields. -// -// CdQueryFidDirentOffset - Accesses the Dirent offset field -// CdQueryFidPathTableNumber - Accesses the PathTable offset field -// CdSetFidDirentOffset - Sets the Dirent offset field -// CdSetFidPathTableNumber - Sets the PathTable ordinal field -// CdFidIsDirectory - Queries if directory bit is set -// CdFidSetDirectory - Sets directory bit -// - -#define FID_DIR_MASK 0x80000000 // high order bit means directory. - -#define CdQueryFidDirentOffset(I) ((I).LowPart & ~FID_DIR_MASK) -#define CdQueryFidPathTableOffset(I) ((I).HighPart) -#define CdSetFidDirentOffset(I,D) ((I).LowPart = D) -#define CdSetFidPathTableOffset(I,P) ((I).HighPart = P) -#define CdFidIsDirectory(I) FlagOn( (I).LowPart, FID_DIR_MASK ) -#define CdFidSetDirectory(I) SetFlag( (I).LowPart, FID_DIR_MASK ) - -#define CdSetFidFromParentAndDirent(I,F,D) { \ - CdSetFidPathTableOffset( (I), CdQueryFidPathTableOffset( (F)->FileId )); \ - CdSetFidDirentOffset( (I), (D)->DirentOffset ); \ - if (FlagOn( (D)->DirentFlags, CD_ATTRIBUTE_DIRECTORY )) { \ - CdFidSetDirectory((I)); \ - } \ -} - -#endif // _CDSTRUC_ - diff --git a/reactos/drivers/filesystems/cdfs_new/cleanup.c b/reactos/drivers/filesystems/cdfs_new/cleanup.c deleted file mode 100755 index 70faad7209c..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/cleanup.c +++ /dev/null @@ -1,332 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - Cleanup.c - -Abstract: - - This module implements the File Cleanup routine for Cdfs called by the - dispatch driver. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_CLEANUP) - - -NTSTATUS -CdCommonCleanup ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the common routine for cleanup of a file/directory called by both - the fsd and fsp threads. - - Cleanup is invoked whenever the last handle to a file object is closed. - This is different than the Close operation which is invoked when the last - reference to a file object is deleted. - - The function of cleanup is to essentially "cleanup" the file/directory - after a user is done with it. The Fcb/Dcb remains around (because MM - still has the file object referenced) but is now available for another - user to open (i.e., as far as the user is concerned the is now closed). - - See close for a more complete description of what close does. - - We do no synchronization in this routine until we get to the point - where we modify the counts, share access and volume lock field. - - We need to update the Fcb and Vcb to show that a user handle has been closed. - The following structures and fields are affected. - - Vcb: - - VolumeLockFileObject - Did the user lock the volume with this file object. - VcbState - Check if we are unlocking the volume here. - VcbCleanup - Count of outstanding handles on the volume. - DirNotifyQueue - If this file object has pending DirNotify Irps. - - Fcb: - - ShareAccess - If this is a user handle. - FcbCleanup - Count of outstanding handles on this Fcb. - Oplock - Any outstanding oplocks on this file object. - FileLock - Any outstanding filelocks on this file object. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation. - ---*/ - -{ - PFILE_OBJECT FileObject; - TYPE_OF_OPEN TypeOfOpen; - - BOOLEAN SendUnlockNotification = FALSE; - BOOLEAN AttemptTeardown; - BOOLEAN VcbAcquired = FALSE; - - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - - KIRQL SavedIrql; - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_IRP( Irp ); - - // - // If we were called with our file system device object instead of a - // volume device object, just complete this request with STATUS_SUCCESS. - // - - if (IrpContext->Vcb == NULL) { - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - return STATUS_SUCCESS; - } - - // - // Get the file object out of the Irp and decode the type of open. - // - - FileObject = IoGetCurrentIrpStackLocation( Irp )->FileObject; - - TypeOfOpen = CdDecodeFileObject( IrpContext, - FileObject, - &Fcb, - &Ccb ); - - // - // No work here for either an UnopenedFile object or a StreamFileObject. - // - - if (TypeOfOpen <= StreamFileOpen) { - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - - return STATUS_SUCCESS; - } - - // - // Keep a local pointer to the Vcb. - // - - Vcb = Fcb->Vcb; - - // - // Synchronise with reads while we set the cleanup complete - // flag on this fileobject. Once this flag is set, any further - // reads will be rejected (CdVerifyFcbOperation) - // - - CdAcquireFileExclusive( IrpContext, Fcb); - - // - // Set the flag in the FileObject to indicate that cleanup is complete. - // - - SetFlag( FileObject->Flags, FO_CLEANUP_COMPLETE ); - - CdReleaseFile( IrpContext, Fcb); - - // - // Acquire the current file. - // - - CdAcquireFcbExclusive( IrpContext, Fcb, FALSE ); - - // - // Use a try-finally to facilitate cleanup. - // - - //try { /* ReactOS Change: Manual removal of SEH since macros to hack around it don't allow multiple SEH usage within one function */ - - // - // Case on the type of open that we are trying to cleanup. - // - - switch (TypeOfOpen) { - - case UserDirectoryOpen: - - // - // Check if we need to complete any dir notify Irps on this file object. - // - - FsRtlNotifyCleanup( Vcb->NotifySync, - &Vcb->DirNotifyList, - Ccb ); - - break; - - case UserFileOpen: - - // - // Coordinate the cleanup operation with the oplock state. - // Oplock cleanup operations can always cleanup immediately so no - // need to check for STATUS_PENDING. - // - - FsRtlCheckOplock( &Fcb->Oplock, - Irp, - IrpContext, - NULL, - NULL ); - - // - // Unlock all outstanding file locks. - // - - if (Fcb->FileLock != NULL) { - - FsRtlFastUnlockAll( Fcb->FileLock, - FileObject, - IoGetRequestorProcess( Irp ), - NULL ); - } - - // - // Cleanup the cache map. - // - - CcUninitializeCacheMap( FileObject, NULL, NULL ); - - // - // Check the fast io state. - // - - CdLockFcb( IrpContext, Fcb ); - Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); - CdUnlockFcb( IrpContext, Fcb ); - - break; - - case UserVolumeOpen : - - break; - - default : - - CdBugCheck( TypeOfOpen, 0, 0 ); - } - - // - // Now lock the Vcb in order to modify the fields in the in-memory - // structures. - // - - CdLockVcb( IrpContext, Vcb ); - - // - // Decrement the cleanup counts in the Vcb and Fcb. - // - - CdDecrementCleanupCounts( IrpContext, Fcb ); - - // - // If the cleanup count hit zero and the volume is not mounted, we - // will want to try to spark teardown. - // - - AttemptTeardown = (Vcb->VcbCleanup == 0 && Vcb->VcbCondition == VcbNotMounted); - - // - // If this file object has locked the volume then perform the unlock operation. - // We do this regardless of explicit or implicit (no share DASD open) lock. - // - - if (FileObject == Vcb->VolumeLockFileObject) { - - ASSERT( FlagOn( Vcb->VcbState, VCB_STATE_LOCKED)); - - IoAcquireVpbSpinLock( &SavedIrql ); - - ClearFlag( Vcb->Vpb->Flags, VPB_LOCKED); - ClearFlag( Vcb->VcbState, VCB_STATE_LOCKED ); - Vcb->VolumeLockFileObject = NULL; - SendUnlockNotification = TRUE; - - IoReleaseVpbSpinLock( SavedIrql ); - } - - CdUnlockVcb( IrpContext, Vcb ); - - // - // We must clean up the share access at this time, since we may not - // get a Close call for awhile if the file was mapped through this - // File Object. - // - - IoRemoveShareAccess( FileObject, &Fcb->ShareAccess ); - - //} finally { /* ReactOS Change: Manual removal of SEH since macros to hack around it don't allow multiple SEH usage within one function */ - - CdReleaseFcb( IrpContext, Fcb ); - - if (SendUnlockNotification) { - - FsRtlNotifyVolumeEvent( FileObject, FSRTL_VOLUME_UNLOCK ); - } - //} /* ReactOS Change: Manual removal of SEH since macros to hack around it don't allow multiple SEH usage within one function */ - - // - // If appropriate, try to spark teardown by purging the volume. Should - // this very fileobject we were cleaning up be the last reason for the - // volume to remain, teardown will commence on completion of this Irp. - // - - if (AttemptTeardown) { - - // - // Preacquire CdData here, since the purges will generate closes which - // may acquire CdData if there is a possibility of tearing the volume - // down. - // - - CdAcquireCdData( IrpContext); - - try { - - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - VcbAcquired = TRUE; - - CdPurgeVolume( IrpContext, Vcb, FALSE ); - - } finally { - - if (VcbAcquired) { CdReleaseVcb( IrpContext, Vcb ); } - - CdReleaseCdData( IrpContext); - } - } - - // - // If this is a normal termination then complete the request - // - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - - return STATUS_SUCCESS; -} - - diff --git a/reactos/drivers/filesystems/cdfs_new/close.c b/reactos/drivers/filesystems/cdfs_new/close.c deleted file mode 100755 index 913c0fd9487..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/close.c +++ /dev/null @@ -1,1028 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - Close.c - -Abstract: - - This module implements the File Close routine for Cdfs called by the - Fsd/Fsp dispatch routines. - - The close operation interacts with both the async and delayed close queues - in the CdData structure. Since close may be called recursively we may - violate the locking order in acquiring the Vcb or Fcb. In this case - we may move the request to the async close queue. If this is the last - reference on the Fcb and there is a chance the user may reopen this - file again soon we would like to defer the close. In this case we - may move the request to the async close queue. - - Once we are past the decode file operation there is no need for the - file object. If we are moving the request to either of the work - queues then we remember all of the information from the file object and - complete the request with STATUS_SUCCESS. The Io system can then - reuse the file object and we can complete the request when convenient. - - The async close queue consists of requests which we would like to - complete as soon as possible. They are queued using the original - IrpContext where some of the fields have been overwritten with - information from the file object. We will extract this information, - cleanup the IrpContext and then call the close worker routine. - - The delayed close queue consists of requests which we would like to - defer the close for. We keep size of this list within a range - determined by the size of the system. We let it grow to some maximum - value and then shrink to some minimum value. We allocate a small - structure which contains the key information from the file object - and use this information along with an IrpContext on the stack - to complete the request. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_CLOSE) - -// -// Local support routines -// - -BOOLEAN -CdCommonClosePrivate ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFCB Fcb, - IN ULONG UserReference, - IN BOOLEAN FromFsd - ); - -VOID -CdQueueClose ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN ULONG UserReference, - IN BOOLEAN DelayedClose - ); - -PIRP_CONTEXT -CdRemoveClose ( - IN PVCB Vcb OPTIONAL - ); - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdCloseWorker ( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCommonClose) -#pragma alloc_text(PAGE, CdCommonClosePrivate) -#pragma alloc_text(PAGE, CdQueueClose) -#pragma alloc_text(PAGE, CdRemoveClose) -#pragma alloc_text(PAGE, CdCloseWorker) -#endif - - -VOID -CdFspClose ( - IN PVCB Vcb OPTIONAL - ) - -/*++ - -Routine Description: - - This routine is called to process the close queues in the CdData. If the - Vcb is passed then we want to remove all of the closes for this Vcb. - Otherwise we will do as many of the delayed closes as we need to do. - -Arguments: - - Vcb - If specified then we are looking for all of the closes for the - given Vcb. - -Return Value: - - None - ---*/ - -{ - PIRP_CONTEXT IrpContext; - IRP_CONTEXT StackIrpContext; - - THREAD_CONTEXT ThreadContext; - - PFCB Fcb; - ULONG UserReference; - - ULONG VcbHoldCount = 0; - PVCB CurrentVcb = NULL; - - BOOLEAN PotentialVcbTeardown = FALSE; - - PAGED_CODE(); - - FsRtlEnterFileSystem(); - - // - // Continue processing until there are no more closes to process. - // - /* ReactOS Change: "GCC suggest parentheses around assignment used as truth value" */ - while ((IrpContext = CdRemoveClose( Vcb ))) { - - // - // If we don't have an IrpContext then use the one on the stack. - // Initialize it for this request. - // - - if (SafeNodeType( IrpContext ) != CDFS_NTC_IRP_CONTEXT ) { - - // - // Update the local values from the IrpContextLite. - // - - Fcb = ((PIRP_CONTEXT_LITE) IrpContext)->Fcb; - UserReference = ((PIRP_CONTEXT_LITE) IrpContext)->UserReference; - - // - // Update the stack irp context with the values from the - // IrpContextLite. - // - - CdInitializeStackIrpContext( &StackIrpContext, - (PIRP_CONTEXT_LITE) IrpContext ); - - // - // Free the IrpContextLite. - // - - CdFreeIrpContextLite( IrpContext ); /* ReactOS Change: GCC "error: invalid lvalue in unary '&'" */ - - // - // Remember we have the IrpContext from the stack. - // - - IrpContext = &StackIrpContext; - - // - // Otherwise cleanup the existing IrpContext. - // - - } else { - - // - // Remember the Fcb and user reference count. - // - - Fcb = (PFCB) IrpContext->Irp; - IrpContext->Irp = NULL; - - UserReference = (ULONG) IrpContext->ExceptionStatus; - IrpContext->ExceptionStatus = STATUS_SUCCESS; - } - - // - // We have an IrpContext. Now we need to set the top level thread - // context. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FSP_FLAGS ); - - // - // If we were given a Vcb then there is a request on top of this. - // - - if (ARGUMENT_PRESENT( Vcb )) { - - ClearFlag( IrpContext->Flags, - IRP_CONTEXT_FLAG_TOP_LEVEL | IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS ); - } - - CdSetThreadContext( IrpContext, &ThreadContext ); - - // - // If we have hit the maximum number of requests to process without - // releasing the Vcb then release the Vcb now. If we are holding - // a different Vcb to this one then release the previous Vcb. - // - // In either case acquire the current Vcb. - // - // We use the MinDelayedCloseCount from the CdData since it is - // a convenient value based on the system size. Only thing we are trying - // to do here is prevent this routine starving other threads which - // may need this Vcb exclusively. - // - // Note that the check for potential teardown below is unsafe. We'll - // repeat later within the cddata lock. - // - - PotentialVcbTeardown = !ARGUMENT_PRESENT( Vcb ) && - (Fcb->Vcb->VcbCondition != VcbMounted) && - (Fcb->Vcb->VcbCondition != VcbMountInProgress) && - (Fcb->Vcb->VcbCleanup == 0); - - if (PotentialVcbTeardown || - (VcbHoldCount > CdData.MinDelayedCloseCount) || - (Fcb->Vcb != CurrentVcb)) { - - if (CurrentVcb != NULL) { - - CdReleaseVcb( IrpContext, CurrentVcb ); - } - - if (PotentialVcbTeardown) { - - CdAcquireCdData( IrpContext ); - - // - // Repeat the checks with global lock held. The volume could have - // been remounted while we didn't hold the lock. - // - - PotentialVcbTeardown = !ARGUMENT_PRESENT( Vcb ) && - (Fcb->Vcb->VcbCondition != VcbMounted) && - (Fcb->Vcb->VcbCondition != VcbMountInProgress) && - (Fcb->Vcb->VcbCleanup == 0); - - if (!PotentialVcbTeardown) { - - CdReleaseCdData( IrpContext); - } - } - - CurrentVcb = Fcb->Vcb; - CdAcquireVcbShared( IrpContext, CurrentVcb, FALSE ); - - VcbHoldCount = 0; - - } else { - - VcbHoldCount += 1; - } - - // - // Call our worker routine to perform the close operation. - // - - CdCommonClosePrivate( IrpContext, CurrentVcb, Fcb, UserReference, FALSE ); - - // - // If the reference count on this Vcb is below our residual reference - // then check if we should dismount the volume. - // - - if (PotentialVcbTeardown) { - - CdReleaseVcb( IrpContext, CurrentVcb ); - CdCheckForDismount( IrpContext, CurrentVcb, FALSE ); - - CurrentVcb = NULL; - - CdReleaseCdData( IrpContext ); - PotentialVcbTeardown = FALSE; - } - - // - // Complete the current request to cleanup the IrpContext. - // - - CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); - } - - // - // Release any Vcb we may still hold. - // - - if (CurrentVcb != NULL) { - - CdReleaseVcb( IrpContext, CurrentVcb ); - - } - - FsRtlExitFileSystem(); -} - - -NTSTATUS -CdCommonClose ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine is the Fsd entry for the close operation. We decode the file - object to find the CDFS structures and type of open. We call our internal - worker routine to perform the actual work. If the work wasn't completed - then we post to one of our worker queues. The Ccb isn't needed after this - point so we delete the Ccb and return STATUS_SUCCESS to our caller in all - cases. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - STATUS_SUCCESS - ---*/ - -{ - TYPE_OF_OPEN TypeOfOpen; - - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - ULONG UserReference = 0; - - BOOLEAN PotentialVcbTeardown = FALSE; - BOOLEAN ForceDismount = FALSE; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_IRP( Irp ); - - // - // If we were called with our file system device object instead of a - // volume device object, just complete this request with STATUS_SUCCESS. - // - - if (IrpContext->Vcb == NULL) { - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - return STATUS_SUCCESS; - } - - // - // Decode the file object to get the type of open and Fcb/Ccb. - // - - TypeOfOpen = CdDecodeFileObject( IrpContext, - IoGetCurrentIrpStackLocation( Irp )->FileObject, - &Fcb, - &Ccb ); - - // - // No work to do for unopened file objects. - // - - if (TypeOfOpen == UnopenedFileObject) { - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - - return STATUS_SUCCESS; - } - - Vcb = Fcb->Vcb; - - // - // Clean up any CCB associated with this open. - // - - if (Ccb != NULL) { - - UserReference = 1; - - // - // Was a FSCTL_DISMOUNT issued on this handle? If so, we need to - // force a dismount of the volume now. - // - - ForceDismount = BooleanFlagOn( Ccb->Flags, CCB_FLAG_DISMOUNT_ON_CLOSE); - - // - // We can always deallocate the Ccb if present. - // - - CdDeleteCcb( IrpContext, Ccb ); - } - - // - // If this is the last reference to a user file or directory on a - // currently mounted volume, then post it to the delayed close queue. Note - // that the VcbCondition check is unsafe, but it doesn't really matter - - // we just might delay the volume teardown a little by posting this close. - // - - if ((Vcb->VcbCondition == VcbMounted) && - (Fcb->FcbReference == 1) && - ((TypeOfOpen == UserFileOpen) || - (TypeOfOpen == UserDirectoryOpen))) { - - CdQueueClose( IrpContext, Fcb, UserReference, TRUE ); - IrpContext = NULL; - - // - // Otherwise try to process this close. Post to the async close queue - // if we can't acquire all of the resources. - // - - } else { - - // - // If we may be dismounting this volume then acquire the CdData - // resource. - // - // Since we now must make volumes go away as soon as reasonable after - // the last user handles closes, key off of the cleanup count. It is - // OK to do this more than neccesary. Since this Fcb could be holding - // a number of other Fcbs (and thus their references), a simple check - // on reference count is not appropriate. - // - // Do an unsafe check first to avoid taking the (global) cddata lock in the - // common case. - // - - if (((Vcb->VcbCleanup == 0) || ForceDismount) && - (Vcb->VcbCondition != VcbMounted)) { - - // - // Possible. Acquire CdData to synchronise with the remount path, and - // then repeat the tests. - // - // Note that we must send the notification outside of any locks, since - // the worker that processes the notify could also be calling into our - // pnp path which wants both CdData and VcbResource. For a force dismount - // the volume will be marked invalid (no going back), so we will definitely - // go ahead and dismount below. - // - - if (ForceDismount) { - - // - // Send notification. - // - - FsRtlNotifyVolumeEvent( IoGetCurrentIrpStackLocation( Irp )->FileObject, - FSRTL_VOLUME_DISMOUNT ); - } - - CdAcquireCdData( IrpContext ); - - if (((Vcb->VcbCleanup == 0) || ForceDismount) && - (Vcb->VcbCondition != VcbMounted) && - (Vcb->VcbCondition != VcbMountInProgress) && - FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL_CDFS )) { - - PotentialVcbTeardown = TRUE; - } - else { - - // - // We can't dismount this volume now, there are other references or - // it's just been remounted. - // - - CdReleaseCdData( IrpContext); - } - } - - if (ForceDismount) { - - // - // Physically disconnect this Vcb from the device so a new mount can - // occur. Vcb deletion cannot happen at this time since there is - // a handle on it associated with this very request, but we'll call - // check for dismount again later anyway. - // - - CdCheckForDismount( IrpContext, Vcb, TRUE ); - } - - // - // Call the worker routine to perform the actual work. This routine - // should never raise except for a fatal error. - // - - if (!CdCommonClosePrivate( IrpContext, Vcb, Fcb, UserReference, TRUE )) { - - // - // If we didn't complete the request then post the request as needed. - // - - CdQueueClose( IrpContext, Fcb, UserReference, FALSE ); - IrpContext = NULL; - - // - // Check whether we should be dismounting the volume and then complete - // the request. - // - - } else if (PotentialVcbTeardown) { - - CdCheckForDismount( IrpContext, Vcb, FALSE ); - } - } - - // - // Always complete this request with STATUS_SUCCESS. - // - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - - if (PotentialVcbTeardown) { - - CdReleaseCdData( IrpContext ); - } - - // - // Always return STATUS_SUCCESS for closes. - // - - return STATUS_SUCCESS; -} - - -// -// Local support routine -// - -BOOLEAN -CdCommonClosePrivate ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFCB Fcb, - IN ULONG UserReference, - IN BOOLEAN FromFsd - ) - -/*++ - -Routine Description: - - This is the worker routine for the close operation. We can be called in - an Fsd thread or from a worker Fsp thread. If called from the Fsd thread - then we acquire the resources without waiting. Otherwise we know it is - safe to wait. - - We check to see whether we should post this request to the delayed close - queue. If we are to process the close here then we acquire the Vcb and - Fcb. We will adjust the counts and call our teardown routine to see - if any of the structures should go away. - -Arguments: - - Vcb - Vcb for this volume. - - Fcb - Fcb for this request. - - UserReference - Number of user references for this file object. This is - zero for an internal stream. - - FromFsd - This request was called from an Fsd thread. Indicates whether - we should wait to acquire resources. - - DelayedClose - Address to store whether we should try to put this on - the delayed close queue. Ignored if this routine can process this - close. - -Return Value: - - BOOLEAN - TRUE if this thread processed the close, FALSE otherwise. - ---*/ - -{ - BOOLEAN RemovedFcb; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - - // - // Try to acquire the Vcb and Fcb. If we can't acquire them then return - // and let our caller know he should post the request to the async - // queue. - // - - if (CdAcquireVcbShared( IrpContext, Vcb, FromFsd )) { - - if (!CdAcquireFcbExclusive( IrpContext, Fcb, FromFsd )) { - - // - // We couldn't get the Fcb. Release the Vcb and let our caller - // know to post this request. - // - - CdReleaseVcb( IrpContext, Vcb ); - return FALSE; - } - - // - // We didn't get the Vcb. Let our caller know to post this request. - // - - } else { - - return FALSE; - } - - // - // Lock the Vcb and decrement the reference counts. - // - - CdLockVcb( IrpContext, Vcb ); - CdDecrementReferenceCounts( IrpContext, Fcb, 1, UserReference ); - CdUnlockVcb( IrpContext, Vcb ); - - // - // Call our teardown routine to see if this object can go away. - // If we don't remove the Fcb then release it. - // - - CdTeardownStructures( IrpContext, Fcb, &RemovedFcb ); - - if (!RemovedFcb) { - - CdReleaseFcb( IrpContext, Fcb ); - } - - // - // Release the Vcb and return to our caller. Let him know we completed - // this request. - // - - CdReleaseVcb( IrpContext, Vcb ); - - return TRUE; -} - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdCloseWorker ( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context - ) -/*++ - -Routine Description: - - Worker routine to call CsFspClose. - -Arguments: - - DeviceObject - Filesystem registration device object - - Context - Callers context - -Return Value: - - None - ---*/ - -{ - CdFspClose (NULL); -} - - -VOID -CdQueueClose ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN ULONG UserReference, - IN BOOLEAN DelayedClose - ) - -/*++ - -Routine Description: - - This routine is called to queue a request to either the async or delayed - close queue. For the delayed queue we need to allocate a smaller - structure to contain the information about the file object. We do - that so we don't put the larger IrpContext structures into this long - lived queue. If we can allocate this structure then we put this - on the async queue instead. - -Arguments: - - Fcb - Fcb for this file object. - - UserReference - Number of user references for this file object. This is - zero for an internal stream. - - DelayedClose - Indicates whether this should go on the async or delayed - close queue. - -Return Value: - - None - ---*/ - -{ - PIRP_CONTEXT_LITE IrpContextLite = NULL; - BOOLEAN StartWorker = FALSE; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_FCB( Fcb ); - - // - // Start with the delayed queue request. We can move this to the async - // queue if there is an allocation failure. - // - - if (DelayedClose) { - - // - // Try to allocate non-paged pool for the IRP_CONTEXT_LITE. - // - - IrpContextLite = CdCreateIrpContextLite( IrpContext ); - } - - // - // We want to clear the top level context in this thread if - // necessary. Call our cleanup routine to do the work. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); - CdCleanupIrpContext( IrpContext, TRUE ); - - // - // Synchronize with the CdData lock. - // - - CdLockCdData(); - - // - // If we have an IrpContext then put the request on the delayed close queue. - // - - if (IrpContextLite != NULL) { - - // - // Initialize the IrpContextLite. - // - - IrpContextLite->NodeTypeCode = CDFS_NTC_IRP_CONTEXT_LITE; - IrpContextLite->NodeByteSize = sizeof( IRP_CONTEXT_LITE ); - IrpContextLite->Fcb = Fcb; - IrpContextLite->UserReference = UserReference; - IrpContextLite->RealDevice = IrpContext->RealDevice; - - // - // Add this to the delayed close list and increment - // the count. - // - - InsertTailList( &CdData.DelayedCloseQueue, - &IrpContextLite->DelayedCloseLinks ); - - CdData.DelayedCloseCount += 1; - - // - // If we are above our threshold then start the delayed - // close operation. - // - - if (CdData.DelayedCloseCount > CdData.MaxDelayedCloseCount) { - - CdData.ReduceDelayedClose = TRUE; - - if (!CdData.FspCloseActive) { - - CdData.FspCloseActive = TRUE; - StartWorker = TRUE; - } - } - - // - // Unlock the CdData. - // - - CdUnlockCdData(); - - // - // Cleanup the IrpContext. - // - - CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); - - // - // Otherwise drop into the async case below. - // - - } else { - - // - // Store the information about the file object into the IrpContext. - // - - IrpContext->Irp = (PIRP) Fcb; - IrpContext->ExceptionStatus = (NTSTATUS) UserReference; - - // - // Add this to the async close list and increment the count. - // - - InsertTailList( &CdData.AsyncCloseQueue, - &IrpContext->WorkQueueItem.List ); - - CdData.AsyncCloseCount += 1; - - // - // Remember to start the Fsp close thread if not currently started. - // - - if (!CdData.FspCloseActive) { - - CdData.FspCloseActive = TRUE; - - StartWorker = TRUE; - } - - // - // Unlock the CdData. - // - - CdUnlockCdData(); - } - - // - // Start the FspClose thread if we need to. - // - - if (StartWorker) { - - IoQueueWorkItem( CdData.CloseItem, CdCloseWorker, CriticalWorkQueue, NULL ); - } - - // - // Return to our caller. - // - - return; -} - - -// -// Local support routine -// - -PIRP_CONTEXT -CdRemoveClose ( - IN PVCB Vcb OPTIONAL - ) - -/*++ - -Routine Description: - -Arguments: - - This routine is called to scan the async and delayed close queues looking - for a suitable entry. If the Vcb is specified then we scan both queues - looking for an entry with the same Vcb. Otherwise we will look in the - async queue first for any close item. If none found there then we look - in the delayed close queue provided that we have triggered the delayed - close operation. - -Return Value: - - PIRP_CONTEXT - NULL if no work item found. Otherwise it is the pointer to - either the IrpContext or IrpContextLite for this request. - ---*/ - -{ - PIRP_CONTEXT IrpContext = NULL; - PIRP_CONTEXT NextIrpContext; - PIRP_CONTEXT_LITE NextIrpContextLite; - - PLIST_ENTRY Entry; - - PAGED_CODE(); - - ASSERT_OPTIONAL_VCB( Vcb ); - - // - // Lock the CdData to perform the scan. - // - - CdLockCdData(); - - // - // First check the list of async closes. - // - - Entry = CdData.AsyncCloseQueue.Flink; - - while (Entry != &CdData.AsyncCloseQueue) { - - // - // Extract the IrpContext. - // - - NextIrpContext = CONTAINING_RECORD( Entry, - IRP_CONTEXT, - WorkQueueItem.List ); - - // - // If no Vcb was specified or this Vcb is for our volume - // then perform the close. - // - - if (!ARGUMENT_PRESENT( Vcb ) || (NextIrpContext->Vcb == Vcb)) { - - RemoveEntryList( Entry ); - CdData.AsyncCloseCount -= 1; - - IrpContext = NextIrpContext; - break; - } - - // - // Move to the next entry. - // - - Entry = Entry->Flink; - } - - // - // If we didn't find anything look through the delayed close - // queue. - // - // We will only check the delayed close queue if we were given - // a Vcb or the delayed close operation is active. - // - - if ((IrpContext == NULL) && - (ARGUMENT_PRESENT( Vcb ) || - (CdData.ReduceDelayedClose && - (CdData.DelayedCloseCount > CdData.MinDelayedCloseCount)))) { - - Entry = CdData.DelayedCloseQueue.Flink; - - while (Entry != &CdData.DelayedCloseQueue) { - - // - // Extract the IrpContext. - // - - NextIrpContextLite = CONTAINING_RECORD( Entry, - IRP_CONTEXT_LITE, - DelayedCloseLinks ); - - // - // If no Vcb was specified or this Vcb is for our volume - // then perform the close. - // - - if (!ARGUMENT_PRESENT( Vcb ) || (NextIrpContextLite->Fcb->Vcb == Vcb)) { - - RemoveEntryList( Entry ); - CdData.DelayedCloseCount -= 1; - - IrpContext = (PIRP_CONTEXT) NextIrpContextLite; - break; - } - - // - // Move to the next entry. - // - - Entry = Entry->Flink; - } - } - - // - // If the Vcb wasn't specified and we couldn't find an entry - // then turn off the Fsp thread. - // - - if (!ARGUMENT_PRESENT( Vcb ) && (IrpContext == NULL)) { - - CdData.FspCloseActive = FALSE; - CdData.ReduceDelayedClose = FALSE; - } - - // - // Unlock the CdData. - // - - CdUnlockCdData(); - - return IrpContext; -} - - - diff --git a/reactos/drivers/filesystems/cdfs_new/create.c b/reactos/drivers/filesystems/cdfs_new/create.c deleted file mode 100755 index 1458ea2d44a..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/create.c +++ /dev/null @@ -1,2916 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - Create.c - -Abstract: - - This module implements the File Create routine for Cdfs called by the - Fsd/Fsp dispatch routines. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_CREATE) - -// -// Local support routines -// - -NTSTATUS -CdNormalizeFileNames ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN BOOLEAN OpenByFileId, - IN BOOLEAN IgnoreCase, - IN TYPE_OF_OPEN RelatedTypeOfOpen, - IN PCCB RelatedCcb OPTIONAL, - IN PUNICODE_STRING RelatedFileName OPTIONAL, - IN OUT PUNICODE_STRING FileName, - IN OUT PCD_NAME RemainingName - ); - -NTSTATUS -CdOpenByFileId ( - IN PIRP_CONTEXT IrpContext, - IN PIO_STACK_LOCATION IrpSp, - IN PVCB Vcb, - IN OUT PFCB *CurrentFcb - ); - -NTSTATUS -CdOpenExistingFcb ( - IN PIRP_CONTEXT IrpContext, - IN PIO_STACK_LOCATION IrpSp, - IN OUT PFCB *CurrentFcb, - IN TYPE_OF_OPEN TypeOfOpen, - IN BOOLEAN IgnoreCase, - IN PCCB RelatedCcb OPTIONAL - ); - -NTSTATUS -CdOpenDirectoryFromPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN PIO_STACK_LOCATION IrpSp, - IN PVCB Vcb, - IN OUT PFCB *CurrentFcb, - IN PCD_NAME DirName, - IN BOOLEAN IgnoreCase, - IN BOOLEAN ShortNameMatch, - IN PPATH_ENTRY PathEntry, - IN BOOLEAN PerformUserOpen, - IN PCCB RelatedCcb OPTIONAL - ); - -NTSTATUS -CdOpenFileFromFileContext ( - IN PIRP_CONTEXT IrpContext, - IN PIO_STACK_LOCATION IrpSp, - IN PVCB Vcb, - IN OUT PFCB *CurrentFcb, - IN PCD_NAME FileName, - IN BOOLEAN IgnoreCase, - IN BOOLEAN ShortNameMatch, - IN PFILE_ENUM_CONTEXT FileContext, - IN PCCB RelatedCcb OPTIONAL - ); - -NTSTATUS -CdCompleteFcbOpen ( - IN PIRP_CONTEXT IrpContext, - PIO_STACK_LOCATION IrpSp, - IN PVCB Vcb, - IN OUT PFCB *CurrentFcb, - IN TYPE_OF_OPEN TypeOfOpen, - IN ULONG UserCcbFlags, - IN ACCESS_MASK DesiredAccess - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCommonCreate) -#pragma alloc_text(PAGE, CdCompleteFcbOpen) -#pragma alloc_text(PAGE, CdNormalizeFileNames) -#pragma alloc_text(PAGE, CdOpenByFileId) -#pragma alloc_text(PAGE, CdOpenDirectoryFromPathEntry) -#pragma alloc_text(PAGE, CdOpenExistingFcb) -#pragma alloc_text(PAGE, CdOpenFileFromFileContext) -#endif - - -NTSTATUS -CdCommonCreate ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the common routine for opening a file called by both the - Fsp and Fsd threads. - - The file can be opened either by name or by file Id either with or without - a relative name. The file name field in the file object passed to this routine - contains either a unicode string or a 64 bit value which is the file Id. - If this is not a Joliet disk then we will convert the unicode name to - an Oem string in this routine. If there is a related file object with - a name then we will already have converted that name to Oem. - - We will store the full name for the file in the file object on a successful - open. We will allocate a larger buffer if necessary and combine the - related and file object names. The only exception is the relative open - when the related file object is for an OpenByFileId file. If we need to - allocate a buffer for a case insensitive name then we allocate it at - the tail of the buffer we will store into the file object. The upcased - portion will begin immediately after the name defined by the FileName - in the file object. - - Once we have the full name in the file object we don't want to split the - name in the event of a retry. We use a flag in the IrpContext to indicate - that the name has been split. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - This is the status from this open operation. - ---*/ - -{ - NTSTATUS Status = STATUS_SUCCESS; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PFILE_OBJECT FileObject; - - COMPOUND_PATH_ENTRY CompoundPathEntry; - BOOLEAN CleanupCompoundPathEntry = FALSE; - - FILE_ENUM_CONTEXT FileContext; - BOOLEAN CleanupFileContext = FALSE; - BOOLEAN FoundEntry; - - PVCB Vcb; - - BOOLEAN OpenByFileId; - BOOLEAN IgnoreCase; - ULONG CreateDisposition; - - BOOLEAN ShortNameMatch; - ULONG ShortNameDirentOffset; - - BOOLEAN VolumeOpen = FALSE; - - // - // We will be acquiring and releasing file Fcb's as we move down the - // directory tree during opens. At any time we need to know the deepest - // point we have traversed down in the tree in case we need to cleanup - // any structures created here. - // - // CurrentFcb - represents this point. If non-null it means we have - // acquired it and need to release it in finally clause. - // - // NextFcb - represents the NextFcb to walk to but haven't acquired yet. - // - - TYPE_OF_OPEN RelatedTypeOfOpen = UnopenedFileObject; - PFILE_OBJECT RelatedFileObject; - PCCB RelatedCcb = NULL; - - PFCB NextFcb; - PFCB CurrentFcb = NULL; - - // - // During the open we need to combine the related file object name - // with the remaining name. We also may need to upcase the file name - // in order to do a case-insensitive name comparison. We also need - // to restore the name in the file object in the event that we retry - // the request. We use the following string variables to manage the - // name. We will can put these strings into either Unicode or Ansi - // form. - // - // FileName - Pointer to name as currently stored in the file - // object. We store the full name into the file object early in - // the open operation. - // - // RelatedFileName - Pointer to the name in the related file object. - // - // RemainingName - String containing remaining name to parse. - // - // MatchingName - Address of name structure in FileContext which matched. - // We need this to know whether we matched the long or short name. - // - - PUNICODE_STRING FileName; - PUNICODE_STRING RelatedFileName = NULL; - - CD_NAME RemainingName; - CD_NAME FinalName; - PCD_NAME MatchingName; - - PAGED_CODE(); - - // - // If we were called with our file system device object instead of a - // volume device object, just complete this request with STATUS_SUCCESS. - // - - if (IrpContext->Vcb == NULL) { - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - return STATUS_SUCCESS; - } - - // - // Get create parameters from the Irp. - // - - OpenByFileId = BooleanFlagOn( IrpSp->Parameters.Create.Options, FILE_OPEN_BY_FILE_ID ); - IgnoreCase = !BooleanFlagOn( IrpSp->Flags, SL_CASE_SENSITIVE ); - CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0x000000ff; - - // - // Do some preliminary checks to make sure the operation is supported. - // We fail in the following cases immediately. - // - // - Open a paging file. - // - Open a target directory. - // - Open a file with Eas. - // - Create a file. - // - - if (FlagOn( IrpSp->Flags, SL_OPEN_PAGING_FILE | SL_OPEN_TARGET_DIRECTORY) || - (IrpSp->Parameters.Create.EaLength != 0) || - (CreateDisposition == FILE_CREATE)) { - - CdCompleteRequest( IrpContext, Irp, STATUS_ACCESS_DENIED ); - return STATUS_ACCESS_DENIED; - } - - // - // Copy the Vcb to a local. Assume the starting directory is the root. - // - - Vcb = IrpContext->Vcb; - NextFcb = Vcb->RootIndexFcb; - - // - // Reference our input parameters to make things easier - // - - FileObject = IrpSp->FileObject; - RelatedFileObject = NULL; - - FileName = &FileObject->FileName; - - // - // Set up the file object's Vpb pointer in case anything happens. - // This will allow us to get a reasonable pop-up. - // - - if ((FileObject->RelatedFileObject != NULL) && !OpenByFileId) { - - RelatedFileObject = FileObject->RelatedFileObject; - FileObject->Vpb = RelatedFileObject->Vpb; - - RelatedTypeOfOpen = CdDecodeFileObject( IrpContext, RelatedFileObject, &NextFcb, &RelatedCcb ); - - // - // Fail the request if this is not a user file object. - // - - if (RelatedTypeOfOpen < UserVolumeOpen) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - // - // Remember the name in the related file object. - // - - RelatedFileName = &RelatedFileObject->FileName; - } - - // - // If we haven't initialized the names then make sure the strings are valid. - // If this an OpenByFileId then verify the file id buffer. - // - // After this routine returns we know that the full name is in the - // FileName buffer and the buffer will hold the upcased portion - // of the name yet to parse immediately after the full name in the - // buffer. Any trailing backslash has been removed and the flag - // in the IrpContext will indicate whether we removed the - // backslash. - // - - Status = CdNormalizeFileNames( IrpContext, - Vcb, - OpenByFileId, - IgnoreCase, - RelatedTypeOfOpen, - RelatedCcb, - RelatedFileName, - FileName, - &RemainingName ); - - // - // Return the error code if not successful. - // - - if (!NT_SUCCESS( Status )) { - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; - } - - // - // We want to acquire the Vcb. Exclusively for a volume open, shared otherwise. - // The file name is empty for a volume open. - // - - if ((FileName->Length == 0) && - (RelatedTypeOfOpen <= UserVolumeOpen) && - !OpenByFileId) { - - VolumeOpen = TRUE; - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - } else { - - CdAcquireVcbShared( IrpContext, Vcb, FALSE ); - } - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Verify that the Vcb is not in an unusable condition. This routine - // will raise if not usable. - // - - CdVerifyVcb( IrpContext, Vcb ); - - // - // If the Vcb is locked then we cannot open another file - // - - if (FlagOn( Vcb->VcbState, VCB_STATE_LOCKED )) { - - try_return( Status = STATUS_ACCESS_DENIED ); - } - - // - // If we are opening this file by FileId then process this immediately - // and exit. - // - - if (OpenByFileId) { - - // - // We only allow Dasd opens of audio disks. Fail this request at - // this point. - // - - if (FlagOn( Vcb->VcbState, VCB_STATE_AUDIO_DISK )) { - - try_return( Status = STATUS_INVALID_DEVICE_REQUEST ); - } - - // - // The only create disposition we allow is OPEN. - // - - if ((CreateDisposition != FILE_OPEN) && - (CreateDisposition != FILE_OPEN_IF)) { - - try_return( Status = STATUS_ACCESS_DENIED ); - } - - // - // Make sure we can wait for this request. - // - - if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - CdRaiseStatus( IrpContext, STATUS_CANT_WAIT ); - } - - try_return( Status = CdOpenByFileId( IrpContext, - IrpSp, - Vcb, - &CurrentFcb )); - } - - // - // If we are opening this volume Dasd then process this immediately - // and exit. - // - - if (VolumeOpen) { - - // - // The only create disposition we allow is OPEN. - // - - if ((CreateDisposition != FILE_OPEN) && - (CreateDisposition != FILE_OPEN_IF)) { - - try_return( Status = STATUS_ACCESS_DENIED ); - } - - // - // If they wanted to open a directory, surprise. - // - - if (FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) { - - try_return( Status = STATUS_NOT_A_DIRECTORY ); - } - - // - // Acquire the Fcb first. - // - - CurrentFcb = Vcb->VolumeDasdFcb; - CdAcquireFcbExclusive( IrpContext, CurrentFcb, FALSE ); - - try_return( Status = CdOpenExistingFcb( IrpContext, - IrpSp, - &CurrentFcb, - UserVolumeOpen, - FALSE, - NULL )); - } - - // - // At this point CurrentFcb points to the deepest Fcb for this open - // in the tree. Let's acquire this Fcb to keep it from being deleted - // beneath us. - // - - CdAcquireFcbExclusive( IrpContext, NextFcb, FALSE ); - CurrentFcb = NextFcb; - - // - // Do a prefix search if there is more of the name to parse. - // - - if (RemainingName.FileName.Length != 0) { - - // - // Do the prefix search to find the longest matching name. - // - - CdFindPrefix( IrpContext, - &CurrentFcb, - &RemainingName.FileName, - IgnoreCase ); - } - - // - // If the remaining name length is zero then we have found our - // target. - // - - if (RemainingName.FileName.Length == 0) { - - // - // If this is a file so verify the user didn't want to open - // a directory. - // - - if (SafeNodeType( CurrentFcb ) == CDFS_NTC_FCB_DATA) { - - if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH ) || - FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) { - - try_return( Status = STATUS_NOT_A_DIRECTORY ); - } - - // - // The only create disposition we allow is OPEN. - // - - if ((CreateDisposition != FILE_OPEN) && - (CreateDisposition != FILE_OPEN_IF)) { - - try_return( Status = STATUS_ACCESS_DENIED ); - } - - try_return( Status = CdOpenExistingFcb( IrpContext, - IrpSp, - &CurrentFcb, - UserFileOpen, - IgnoreCase, - RelatedCcb )); - - // - // This is a directory. Verify the user didn't want to open - // as a file. - // - - } else if (FlagOn( IrpSp->Parameters.Create.Options, FILE_NON_DIRECTORY_FILE )) { - - try_return( Status = STATUS_FILE_IS_A_DIRECTORY ); - - // - // Open the file as a directory. - // - - } else { - - // - // The only create disposition we allow is OPEN. - // - - if ((CreateDisposition != FILE_OPEN) && - (CreateDisposition != FILE_OPEN_IF)) { - - try_return( Status = STATUS_ACCESS_DENIED ); - } - - try_return( Status = CdOpenExistingFcb( IrpContext, - IrpSp, - &CurrentFcb, - UserDirectoryOpen, - IgnoreCase, - RelatedCcb )); - } - } - - // - // We have more work to do. We have a starting Fcb which we own shared. - // We also have the remaining name to parse. Walk through the name - // component by component looking for the full name. - // - - // - // Our starting Fcb better be a directory. - // - - if (!FlagOn( CurrentFcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) { - - try_return( Status = STATUS_OBJECT_PATH_NOT_FOUND ); - } - - // - // If we can't wait then post this request. - // - - if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - CdRaiseStatus( IrpContext, STATUS_CANT_WAIT ); - } - - // - // Make sure the final name has no version string. - // - - FinalName.VersionString.Length = 0; - - while (TRUE) { - - ShortNameMatch = FALSE; - - // - // Split off the next component from the name. - // - - CdDissectName( IrpContext, - &RemainingName.FileName, - &FinalName.FileName ); - - // - // Go ahead and look this entry up in the path table. - // - - CdInitializeCompoundPathEntry( IrpContext, &CompoundPathEntry ); - CleanupCompoundPathEntry = TRUE; - - FoundEntry = CdFindPathEntry( IrpContext, - CurrentFcb, - &FinalName, - IgnoreCase, - &CompoundPathEntry ); - - // - // If we didn't find the entry then check if the current name - // is a possible short name. - // - - if (!FoundEntry) { - - ShortNameDirentOffset = CdShortNameDirentOffset( IrpContext, &FinalName.FileName ); - - // - // If there is an embedded short name offset then look for the - // matching long name in the directory. - // - - if (ShortNameDirentOffset != MAXULONG) { - - if (CleanupFileContext) { - - CdCleanupFileContext( IrpContext, &FileContext ); - } - - CdInitializeFileContext( IrpContext, &FileContext ); - CleanupFileContext = TRUE; - - FoundEntry = CdFindFileByShortName( IrpContext, - CurrentFcb, - &FinalName, - IgnoreCase, - ShortNameDirentOffset, - &FileContext ); - - // - // If we found an entry and it is a directory then look - // this up in the path table. - // - - if (FoundEntry) { - - ShortNameMatch = TRUE; - - if (FlagOn( FileContext.InitialDirent->Dirent.DirentFlags, - CD_ATTRIBUTE_DIRECTORY )) { - - CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry ); - CdInitializeCompoundPathEntry( IrpContext, &CompoundPathEntry ); - - FoundEntry = CdFindPathEntry( IrpContext, - CurrentFcb, - &FileContext.InitialDirent->Dirent.CdCaseFileName, - IgnoreCase, - &CompoundPathEntry ); - - // - // We better find this entry. - // - - if (!FoundEntry) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - // - // Upcase the name with the short name if case - // insensitive. - // - - if (IgnoreCase) { - - CdUpcaseName( IrpContext, &FinalName, &FinalName ); - } - - // - // We found a matching file. If we are at the last - // entry then break out of the loop and open the - // file below. Otherwise we return an error. - // - - } else if (RemainingName.FileName.Length == 0) { - - // - // Break out of the loop. We will process the dirent - // below. - // - - MatchingName = &FileContext.ShortName; - break; - - } else { - - try_return( Status = STATUS_OBJECT_PATH_NOT_FOUND ); - } - } - } - - // - // We didn't find the name in either the path table or as - // a short name in a directory. If the remaining name - // length is zero then break out of the loop to search - // the directory. - // - - if (!FoundEntry) { - - if (RemainingName.FileName.Length == 0) { - - break; - - // - // Otherwise this path could not be cracked. - // - - } else { - - try_return( Status = STATUS_OBJECT_PATH_NOT_FOUND ); - } - } - } - - // - // If this is an ignore case open then copy the exact case - // in the file object name. If it was a short name match then - // the name must be upcase already. - // - - if (IgnoreCase && !ShortNameMatch) { - - RtlCopyMemory( FinalName.FileName.Buffer, - CompoundPathEntry.PathEntry.CdDirName.FileName.Buffer, - CompoundPathEntry.PathEntry.CdDirName.FileName.Length ); - } - - // - // If we have found the last component then open this as a directory - // and return to our caller. - // - - if (RemainingName.FileName.Length == 0) { - - if (FlagOn( IrpSp->Parameters.Create.Options, FILE_NON_DIRECTORY_FILE )) { - - try_return( Status = STATUS_FILE_IS_A_DIRECTORY ); - } - - // - // The only create disposition we allow is OPEN. - // - - if ((CreateDisposition != FILE_OPEN) && - (CreateDisposition != FILE_OPEN_IF)) { - - try_return( Status = STATUS_ACCESS_DENIED ); - } - - try_return( Status = CdOpenDirectoryFromPathEntry( IrpContext, - IrpSp, - Vcb, - &CurrentFcb, - &FinalName, - IgnoreCase, - ShortNameMatch, - &CompoundPathEntry.PathEntry, - TRUE, - RelatedCcb )); - } - - // - // Otherwise open an Fcb for this intermediate index Fcb. - // - - CdOpenDirectoryFromPathEntry( IrpContext, - IrpSp, - Vcb, - &CurrentFcb, - &FinalName, - IgnoreCase, - ShortNameMatch, - &CompoundPathEntry.PathEntry, - FALSE, - NULL ); - - CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry ); - CleanupCompoundPathEntry = FALSE; - } - - // - // We need to scan the current directory for a matching file name - // if we don't already have one. - // - - if (!FoundEntry) { - - if (CleanupFileContext) { - - CdCleanupFileContext( IrpContext, &FileContext ); - } - - CdInitializeFileContext( IrpContext, &FileContext ); - CleanupFileContext = TRUE; - - // - // Split our search name into separate components. - // - - CdConvertNameToCdName( IrpContext, &FinalName ); - - FoundEntry = CdFindFile( IrpContext, - CurrentFcb, - &FinalName, - IgnoreCase, - &FileContext, - &MatchingName ); - } - - // - // If we didn't find a match then check if the name is invalid to - // determine which error code to return. - // - - if (!FoundEntry) { - - if ((CreateDisposition == FILE_OPEN) || - (CreateDisposition == FILE_OVERWRITE)) { - - try_return( Status = STATUS_OBJECT_NAME_NOT_FOUND ); - } - - // - // Any other operation return STATUS_ACCESS_DENIED. - // - - try_return( Status = STATUS_ACCESS_DENIED ); - } - - // - // If this is a directory then the disk is corrupt because it wasn't - // in the Path Table. - // - - if (FlagOn( FileContext.InitialDirent->Dirent.Flags, CD_ATTRIBUTE_DIRECTORY )) { - - CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); - } - - // - // Make sure our opener didn't want a directory. - // - - if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH ) || - FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) { - - try_return( Status = STATUS_NOT_A_DIRECTORY ); - } - - // - // The only create disposition we allow is OPEN. - // - - if ((CreateDisposition != FILE_OPEN) && - (CreateDisposition != FILE_OPEN_IF)) { - - try_return( Status = STATUS_ACCESS_DENIED ); - } - - // - // If this is an ignore case open then copy the exact case - // in the file object name. Any version portion should - // already be upcased. - // - - if (IgnoreCase) { - - RtlCopyMemory( FinalName.FileName.Buffer, - MatchingName->FileName.Buffer, - MatchingName->FileName.Length ); - } - - // - // Open the file using the file context. We already have the - // first and last dirents. - // - - try_return( Status = CdOpenFileFromFileContext( IrpContext, - IrpSp, - Vcb, - &CurrentFcb, - &FinalName, - IgnoreCase, - (BOOLEAN) (MatchingName == &FileContext.ShortName), - &FileContext, - RelatedCcb )); - - try_exit: NOTHING; - } finally { - - // - // Cleanup the PathEntry if initialized. - // - - if (CleanupCompoundPathEntry) { - - CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry ); - } - - // - // Cleanup the FileContext if initialized. - // - - if (CleanupFileContext) { - - CdCleanupFileContext( IrpContext, &FileContext ); - } - - // - // The result of this open could be success, pending or some error - // condition. - // - - if (AbnormalTermination()) { - - - // - // In the error path we start by calling our teardown routine if we - // have a CurrentFcb. - // - - if (CurrentFcb != NULL) { - - BOOLEAN RemovedFcb; - - CdTeardownStructures( IrpContext, CurrentFcb, &RemovedFcb ); - - if (RemovedFcb) { - - CurrentFcb = NULL; - } - } - - // - // No need to complete the request. - // - - IrpContext = NULL; - Irp = NULL; - - // - // If we posted this request through the oplock package we need - // to show that there is no reason to complete the request. - // - - } else if (Status == STATUS_PENDING) { - - IrpContext = NULL; - Irp = NULL; - } - - // - // Release the Current Fcb if still acquired. - // - - if (CurrentFcb != NULL) { - - CdReleaseFcb( IrpContext, CurrentFcb ); - } - - // - // Release the Vcb. - // - - CdReleaseVcb( IrpContext, Vcb ); - - // - // Call our completion routine. It will handle the case where either - // the Irp and/or IrpContext are gone. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - } - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdNormalizeFileNames ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN BOOLEAN OpenByFileId, - IN BOOLEAN IgnoreCase, - IN TYPE_OF_OPEN RelatedTypeOfOpen, - IN PCCB RelatedCcb OPTIONAL, - IN PUNICODE_STRING RelatedFileName OPTIONAL, - IN OUT PUNICODE_STRING FileName, - IN OUT PCD_NAME RemainingName - ) - -/*++ - -Routine Description: - - This routine is called to store the full name and upcased name into the - filename buffer. We only upcase the portion yet to parse. We also - check for a trailing backslash and lead-in double backslashes. This - routine also verifies the mode of the related open against the name - currently in the filename. - -Arguments: - - Vcb - Vcb for this volume. - - OpenByFileId - Indicates if the filename should be a 64 bit FileId. - - IgnoreCase - Indicates if this open is a case-insensitive operation. - - RelatedTypeOfOpen - Indicates the type of the related file object. - - RelatedCcb - Ccb for the related open. Ignored if no relative open. - - RelatedFileName - FileName buffer for related open. Ignored if no - relative open. - - FileName - FileName to update in this routine. The name should - either be a 64-bit FileId or a Unicode string. - - RemainingName - Name with the remaining portion of the name. This - will begin after the related name and any separator. For a - non-relative open we also step over the initial separator. - -Return Value: - - NTSTATUS - STATUS_SUCCESS if the names are OK, appropriate error code - otherwise. - ---*/ - -{ - ULONG RemainingNameLength; - ULONG RelatedNameLength = 0; - ULONG SeparatorLength = 0; - - ULONG BufferLength; - - UNICODE_STRING NewFileName; - - PAGED_CODE(); - - // - // If this is the first pass then we need to build the full name and - // check for name compatibility. - // - - if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_FULL_NAME )) { - - // - // Deal with the regular file name case first. - // - - if (!OpenByFileId) { - - // - // This is here because the Win32 layer can't avoid sending me double - // beginning backslashes. - // - - if ((FileName->Length > sizeof( WCHAR )) && - (FileName->Buffer[1] == L'\\') && - (FileName->Buffer[0] == L'\\')) { - - // - // If there are still two beginning backslashes, the name is bogus. - // - - if ((FileName->Length > 2 * sizeof( WCHAR )) && - (FileName->Buffer[2] == L'\\')) { - - return STATUS_OBJECT_NAME_INVALID; - } - - // - // Slide the name down in the buffer. - // - - FileName->Length -= sizeof( WCHAR ); - - RtlMoveMemory( FileName->Buffer, - FileName->Buffer + 1, - FileName->Length ); - } - - // - // Check for a trailing backslash. Don't strip off if only character - // in the full name or for relative opens where this is illegal. - // - - if (((FileName->Length > sizeof( WCHAR)) || - ((FileName->Length == sizeof( WCHAR )) && (RelatedTypeOfOpen == UserDirectoryOpen))) && - (FileName->Buffer[ (FileName->Length/2) - 1 ] == L'\\')) { - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH ); - FileName->Length -= sizeof( WCHAR ); - } - - // - // Remember the length we need for this portion of the name. - // - - RemainingNameLength = FileName->Length; - - // - // If this is a related file object then we verify the compatibility - // of the name in the file object with the relative file object. - // - - if (RelatedTypeOfOpen != UnopenedFileObject) { - - // - // If the filename length was zero then it must be legal. - // If there are characters then check with the related - // type of open. - // - - if (FileName->Length != 0) { - - // - // The name length must always be zero for a volume open. - // - - if (RelatedTypeOfOpen <= UserVolumeOpen) { - - return STATUS_INVALID_PARAMETER; - - // - // The remaining name cannot begin with a backslash. - // - - } else if (FileName->Buffer[0] == L'\\' ) { - - return STATUS_INVALID_PARAMETER; - - // - // If the related file is a user file then there - // is no file with this path. - // - - } else if (RelatedTypeOfOpen == UserFileOpen) { - - return STATUS_OBJECT_PATH_NOT_FOUND; - } - } - - // - // Remember the length of the related name when building - // the full name. We leave the RelatedNameLength and - // SeparatorLength at zero if the relative file is opened - // by Id. - // - - if (!FlagOn( RelatedCcb->Flags, CCB_FLAG_OPEN_BY_ID )) { - - // - // Add a separator if the name length is non-zero - // unless the relative Fcb is at the root. - // - - if ((FileName->Length != 0) && - (RelatedCcb->Fcb != Vcb->RootIndexFcb)) { - - SeparatorLength = sizeof( WCHAR ); - } - - RelatedNameLength = RelatedFileName->Length; - } - - // - // The full name is already in the filename. It must either - // be length 0 or begin with a backslash. - // - - } else if (FileName->Length != 0) { - - if (FileName->Buffer[0] != L'\\') { - - return STATUS_INVALID_PARAMETER; - } - - // - // We will want to trim the leading backslash from the - // remaining name we return. - // - - RemainingNameLength -= sizeof( WCHAR ); - SeparatorLength = sizeof( WCHAR ); - } - - // - // Now see if the buffer is large enough to hold the full name. - // - - BufferLength = RelatedNameLength + SeparatorLength + RemainingNameLength; - - // - // Check for an overflow of the maximum filename size. - // - - if (BufferLength > MAXUSHORT) { - - return STATUS_INVALID_PARAMETER; - } - - // - // Now see if we need to allocate a new buffer. - // - - if (FileName->MaximumLength < BufferLength) { - - NewFileName.Buffer = FsRtlAllocatePoolWithTag( CdPagedPool, - BufferLength, - TAG_FILE_NAME ); - - NewFileName.MaximumLength = (USHORT) BufferLength; - - } else { - - NewFileName.Buffer = FileName->Buffer; - NewFileName.MaximumLength = FileName->MaximumLength; - } - - // - // If there is a related name then we need to slide the remaining bytes up and - // insert the related name. Otherwise the name is in the correct position - // already. - // - - if (RelatedNameLength != 0) { - - // - // Store the remaining name in its correct position. - // - - if (RemainingNameLength != 0) { - - RtlMoveMemory( Add2Ptr( NewFileName.Buffer, RelatedNameLength + SeparatorLength, PVOID ), - FileName->Buffer, - RemainingNameLength ); - } - - RtlCopyMemory( NewFileName.Buffer, - RelatedFileName->Buffer, - RelatedNameLength ); - - // - // Add the separator if needed. - // - - if (SeparatorLength != 0) { - - *(Add2Ptr( NewFileName.Buffer, RelatedNameLength, PWCHAR )) = L'\\'; - } - - // - // Update the filename value we got from the user. - // - - if (NewFileName.Buffer != FileName->Buffer) { - - if (FileName->Buffer != NULL) { - - CdFreePool( &FileName->Buffer ); - } - - FileName->Buffer = NewFileName.Buffer; - FileName->MaximumLength = NewFileName.MaximumLength; - } - - // - // Copy the name length to the user's filename. - // - - FileName->Length = (USHORT) (RelatedNameLength + SeparatorLength + RemainingNameLength); - } - - // - // Now update the remaining name to parse. - // - - RemainingName->FileName.MaximumLength = - RemainingName->FileName.Length = (USHORT) RemainingNameLength; - RemainingName->VersionString.Length = 0; - - RemainingName->FileName.Buffer = Add2Ptr( FileName->Buffer, - RelatedNameLength + SeparatorLength, - PWCHAR ); - - // - // Upcase the name if necessary. - // - - if (IgnoreCase && (RemainingNameLength != 0)) { - - CdUpcaseName( IrpContext, - RemainingName, - RemainingName ); - } - - // - // Do a quick check to make sure there are no wildcards. - // - - if (FsRtlDoesNameContainWildCards( &RemainingName->FileName )) { - - return STATUS_OBJECT_NAME_INVALID; - } - - // - // For the open by file Id case we verify the name really contains - // a 64 bit value. - // - - } else { - - // - // Check for validity of the buffer. - // - - if (FileName->Length != sizeof( FILE_ID )) { - - return STATUS_INVALID_PARAMETER; - } - } - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_FULL_NAME ); - - // - // If we are in the retry path then the full name is already in the - // file object name. If this is a case-sensitive operation then - // we need to upcase the name from the end of any related file name already stored - // there. - // - - } else { - - // - // Assume there is no relative name. - // - - RemainingName->FileName = *FileName; - RemainingName->VersionString.Length = 0; - - // - // Nothing to do if the name length is zero. - // - - if (RemainingName->FileName.Length != 0) { - - // - // If there is a relative name then we need to walk past it. - // - - if (RelatedTypeOfOpen != UnopenedFileObject) { - - // - // Nothing to walk past if the RelatedCcb is opened by FileId. - // - - - if (!FlagOn( RelatedCcb->Flags, CCB_FLAG_OPEN_BY_ID )) { - - // - // Related file name is a proper prefix of the full name. - // We step over the related name and if we are then - // pointing at a separator character we step over that. - // - - RemainingName->FileName.Buffer = Add2Ptr( RemainingName->FileName.Buffer, - RelatedFileName->Length, - PWCHAR ); - - RemainingName->FileName.Length -= RelatedFileName->Length; - } - } - - // - // If we are pointing at a separator character then step past that. - // - - if (RemainingName->FileName.Length != 0) { - - if (*(RemainingName->FileName.Buffer) == L'\\') { - - RemainingName->FileName.Buffer = Add2Ptr( RemainingName->FileName.Buffer, - sizeof( WCHAR ), - PWCHAR ); - - RemainingName->FileName.Length -= sizeof( WCHAR ); - } - } - } - - // - // Upcase the name if necessary. - // - - if (IgnoreCase && (RemainingName->FileName.Length != 0)) { - - CdUpcaseName( IrpContext, - RemainingName, - RemainingName ); - } - } - - return STATUS_SUCCESS; -} - - -// -// Local support routine -// - -NTSTATUS -CdOpenByFileId ( - IN PIRP_CONTEXT IrpContext, - IN PIO_STACK_LOCATION IrpSp, - IN PVCB Vcb, - IN OUT PFCB *CurrentFcb - ) - -/*++ - -Routine Description: - - This routine is called to open a file by the FileId. The file Id is in - the FileObject name buffer and has been verified to be 64 bits. - - We extract the Id number and then check to see whether we are opening a - file or directory and compare that with the create options. If this - generates no error then optimistically look up the Fcb in the Fcb Table. - - If we don't find the Fcb then we need to carefully verify there is a file - at this offset. First check whether the Parent Fcb is in the table. If - not then lookup the parent at the path table offset given by file ID. - - If found then build the Fcb from this entry and store the new Fcb in the - tree. - - We know have the parent Fcb. Do a directory scan to find the dirent at - the given offset in this stream. This must point to the first entry - of a valid file. - - Finally we call our worker routine to complete the open on this Fcb. - -Arguments: - - IrpSp - Stack location within the create Irp. - - Vcb - Vcb for this volume. - - CurrentFcb - Address to store the Fcb for this open. We only store the - CurrentFcb here when we have acquired it so our caller knows to - free or deallocate it. - -Return Value: - - NTSTATUS - Status indicating the result of the operation. - ---*/ - -{ - NTSTATUS Status = STATUS_ACCESS_DENIED; - - BOOLEAN UnlockVcb = FALSE; - BOOLEAN Found; - - ULONG StreamOffset; - - NODE_TYPE_CODE NodeTypeCode; - TYPE_OF_OPEN TypeOfOpen; - - FILE_ENUM_CONTEXT FileContext; - BOOLEAN CleanupFileContext = FALSE; - - COMPOUND_PATH_ENTRY CompoundPathEntry; - BOOLEAN CleanupCompoundPathEntry = FALSE; - - FILE_ID FileId; - FILE_ID ParentFileId; - - PFCB NextFcb; - - PAGED_CODE(); - - // - // Extract the FileId from the FileObject. - // - - RtlCopyMemory( &FileId, IrpSp->FileObject->FileName.Buffer, sizeof( FILE_ID )); - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Go ahead and figure out the TypeOfOpen and NodeType. We can - // get these from the input FileId. - // - - if (CdFidIsDirectory( FileId )) { - - TypeOfOpen = UserDirectoryOpen; - NodeTypeCode = CDFS_NTC_FCB_INDEX; - - // - // If the offset isn't zero then the file Id is bad. - // - - if (CdQueryFidDirentOffset( FileId ) != 0) { - - try_return( Status = STATUS_INVALID_PARAMETER ); - } - - } else { - - TypeOfOpen = UserFileOpen; - NodeTypeCode = CDFS_NTC_FCB_DATA; - } - - // - // Acquire the Vcb and check if there is already an Fcb. - // If not we will need to carefully verify the Fcb. - // We will post the request if we don't find the Fcb and this - // request can't wait. - // - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - - NextFcb = CdLookupFcbTable( IrpContext, Vcb, FileId ); - - if (NextFcb == NULL) { - - // - // Get the path table offset from the file id. - // - - StreamOffset = CdQueryFidPathTableOffset( FileId ); - - // - // Build the parent FileId for this and try looking it - // up in the PathTable. - // - - CdSetFidDirentOffset( ParentFileId, 0 ); - CdSetFidPathTableOffset( ParentFileId, StreamOffset ); - CdFidSetDirectory( ParentFileId ); - - NextFcb = CdLookupFcbTable( IrpContext, Vcb, ParentFileId ); - - // - // If not present then walk through the PathTable to this point. - // - - if (NextFcb == NULL) { - - CdUnlockVcb( IrpContext, Vcb ); - UnlockVcb = FALSE; - - // - // Check that the path table offset lies within the path - // table. - // - - if (StreamOffset > Vcb->PathTableFcb->FileSize.LowPart) { - - try_return( Status = STATUS_INVALID_PARAMETER ); - } - - CdInitializeCompoundPathEntry( IrpContext, &CompoundPathEntry ); - CleanupCompoundPathEntry = TRUE; - - // - // Start at the first entry in the PathTable. - // - - CdLookupPathEntry( IrpContext, - Vcb->PathTableFcb->StreamOffset, - 1, - TRUE, - &CompoundPathEntry ); - - // - // Continue looking until we have passed our target offset. - // - - while (TRUE) { - - // - // Move to the next entry. - // - - Found = CdLookupNextPathEntry( IrpContext, - &CompoundPathEntry.PathContext, - &CompoundPathEntry.PathEntry ); - - // - // If we didn't find the entry or are beyond it then the - // input Id is invalid. - // - - if (!Found || - (CompoundPathEntry.PathEntry.PathTableOffset > StreamOffset)) { - - try_return( Status = STATUS_INVALID_PARAMETER ); - } - } - - // - // If the FileId specified a directory then we have found - // the entry. Make sure our caller wanted to open a directory. - // - - if ((TypeOfOpen == UserDirectoryOpen) && - FlagOn( IrpSp->Parameters.Create.Options, FILE_NON_DIRECTORY_FILE )) { - - try_return( Status = STATUS_FILE_IS_A_DIRECTORY ); - } - - // - // Lock the Vcb and create the Fcb if necessary. - // - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - - NextFcb = CdCreateFcb( IrpContext, ParentFileId, NodeTypeCode, &Found ); - - // - // It's possible that someone got in here ahead of us. - // - - if (!Found) { - - CdInitializeFcbFromPathEntry( IrpContext, - NextFcb, - NULL, - &CompoundPathEntry.PathEntry ); - } - - // - // If the user wanted to open a directory then we have found - // it. Store this Fcb into the CurrentFcb and skip the - // directory scan. - // - - if (TypeOfOpen == UserDirectoryOpen) { - - *CurrentFcb = NextFcb; - NextFcb = NULL; - } - } - - // - // Perform the directory scan if we don't already have our target. - // - - if (NextFcb != NULL) { - - // - // Acquire the parent. We currently own the Vcb lock so - // do this without waiting first. - // - - if (!CdAcquireFcbExclusive( IrpContext, - NextFcb, - TRUE )) { - - NextFcb->FcbReference += 1; - CdUnlockVcb( IrpContext, Vcb ); - - CdAcquireFcbExclusive( IrpContext, NextFcb, FALSE ); - - CdLockVcb( IrpContext, Vcb ); - NextFcb->FcbReference -= 1; - CdUnlockVcb( IrpContext, Vcb ); - - } else { - - CdUnlockVcb( IrpContext, Vcb ); - } - - UnlockVcb = FALSE; - - // - // Set up the CurrentFcb pointers. We know there was - // no previous parent in this case. - // - - *CurrentFcb = NextFcb; - - // - // Calculate the offset in the stream. - // - - StreamOffset = CdQueryFidDirentOffset( FileId ); - - // - // Create the stream file if it doesn't exist. This will update - // the Fcb with the size from the self entry. - // - - if (NextFcb->FileObject == NULL) { - - CdCreateInternalStream( IrpContext, Vcb, NextFcb ); - } - - // - // If our offset is beyond the end of the directory then the - // FileId is invalid. - // - - if (StreamOffset > NextFcb->FileSize.LowPart) { - - try_return( Status = STATUS_INVALID_PARAMETER ); - } - - // - // Otherwise position ourselves at the self entry and walk - // through dirent by dirent until this location is found. - // - - CdInitializeFileContext( IrpContext, &FileContext ); - CdLookupInitialFileDirent( IrpContext, - NextFcb, - &FileContext, - NextFcb->StreamOffset ); - - CleanupFileContext = TRUE; - - while (TRUE) { - - // - // Move to the first entry of the next file. - // - - Found = CdLookupNextInitialFileDirent( IrpContext, - NextFcb, - &FileContext ); - - // - // If we didn't find the entry or are beyond it then the - // input Id is invalid. - // - - if (!Found || - (FileContext.InitialDirent->Dirent.DirentOffset > StreamOffset)) { - - try_return( Status = STATUS_INVALID_PARAMETER ); - } - } - - // - // This better not be a directory. Directory FileIds must - // refer to the self entry for directories. - // - - if (FlagOn( FileContext.InitialDirent->Dirent.DirentFlags, - CD_ATTRIBUTE_DIRECTORY )) { - - try_return( Status = STATUS_INVALID_PARAMETER ); - } - - // - // Check that our caller wanted to open a file. - // - - if (FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) { - - try_return( Status = STATUS_NOT_A_DIRECTORY ); - } - - // - // Otherwise we want to collect all of the dirents for this file - // and create an Fcb with this. - // - - CdLookupLastFileDirent( IrpContext, NextFcb, &FileContext ); - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - - NextFcb = CdCreateFcb( IrpContext, FileId, NodeTypeCode, &Found ); - - // - // It's possible that someone has since created this Fcb since we - // first checked. If so then can simply use this. Otherwise - // we need to initialize a new Fcb and attach it to our parent - // and insert it into the Fcb Table. - // - - if (!Found) { - - CdInitializeFcbFromFileContext( IrpContext, - NextFcb, - *CurrentFcb, - &FileContext ); - } - } - - // - // We have the Fcb. Check that the type of the file is compatible with - // the desired type of file to open. - // - - } else { - - if (FlagOn( NextFcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) { - - if (FlagOn( IrpSp->Parameters.Create.Options, FILE_NON_DIRECTORY_FILE )) { - - try_return( Status = STATUS_FILE_IS_A_DIRECTORY ); - } - - } else if (FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) { - - try_return( Status = STATUS_NOT_A_DIRECTORY ); - } - } - - // - // If we have a the previous Fcb and have inserted the next Fcb into - // the Fcb Table. It is safe to release the current Fcb if present - // since it is referenced through the child Fcb. - // - - if (*CurrentFcb != NULL) { - - CdReleaseFcb( IrpContext, *CurrentFcb ); - } - - // - // We now know the Fcb and currently hold the Vcb lock. - // Try to acquire this Fcb without waiting. Otherwise we - // need to reference it, drop the Vcb, acquire the Fcb and - // then dereference the Fcb. - // - - if (!CdAcquireFcbExclusive( IrpContext, NextFcb, TRUE )) { - - NextFcb->FcbReference += 1; - - CdUnlockVcb( IrpContext, Vcb ); - - CdAcquireFcbExclusive( IrpContext, NextFcb, FALSE ); - - CdLockVcb( IrpContext, Vcb ); - NextFcb->FcbReference -= 1; - CdUnlockVcb( IrpContext, Vcb ); - - } else { - - CdUnlockVcb( IrpContext, Vcb ); - } - - UnlockVcb = FALSE; - - // - // Move to this Fcb. - // - - *CurrentFcb = NextFcb; - - // - // Check the requested access on this Fcb. - // - - if (!CdIllegalFcbAccess( IrpContext, - TypeOfOpen, - IrpSp->Parameters.Create.SecurityContext->DesiredAccess )) { - - // - // Call our worker routine to complete the open. - // - - Status = CdCompleteFcbOpen( IrpContext, - IrpSp, - Vcb, - CurrentFcb, - TypeOfOpen, - CCB_FLAG_OPEN_BY_ID, - IrpSp->Parameters.Create.SecurityContext->DesiredAccess ); - } - - try_exit: NOTHING; - } finally { - - if (UnlockVcb) { - - CdUnlockVcb( IrpContext, Vcb ); - } - - if (CleanupFileContext) { - - CdCleanupFileContext( IrpContext, &FileContext ); - } - - if (CleanupCompoundPathEntry) { - - CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry ); - } - } - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdOpenExistingFcb ( - IN PIRP_CONTEXT IrpContext, - IN PIO_STACK_LOCATION IrpSp, - IN OUT PFCB *CurrentFcb, - IN TYPE_OF_OPEN TypeOfOpen, - IN BOOLEAN IgnoreCase, - IN PCCB RelatedCcb OPTIONAL - ) - -/*++ - -Routine Description: - - This routine is called to open an Fcb which is already in the Fcb table. - We will verify the access to the file and then call our worker routine - to perform the final operations. - -Arguments: - - IrpSp - Pointer to the stack location for this open. - - CurrentFcb - Address of Fcb to open. We will clear this if the Fcb - is released here. - - TypeOfOpen - Indicates whether we are opening a file, directory or volume. - - IgnoreCase - Indicates if this open is case-insensitive. - - RelatedCcb - Ccb for related file object if relative open. We use - this when setting the Ccb flags for this open. It will tell - us whether the name currently in the file object is relative or - absolute. - -Return Value: - - NTSTATUS - Status indicating the result of the operation. - ---*/ - -{ - ULONG CcbFlags = 0; - - NTSTATUS Status = STATUS_ACCESS_DENIED; - - PAGED_CODE(); - - // - // Check that the desired access is legal. - // - - if (!CdIllegalFcbAccess( IrpContext, - TypeOfOpen, - IrpSp->Parameters.Create.SecurityContext->DesiredAccess )) { - - // - // Set the Ignore case. - // - - if (IgnoreCase) { - - SetFlag( CcbFlags, CCB_FLAG_IGNORE_CASE ); - } - - // - // Check the related Ccb to see if this was an OpenByFileId and - // whether there was a version. - // - - if (ARGUMENT_PRESENT( RelatedCcb )) { - - SetFlag( CcbFlags, FlagOn( RelatedCcb->Flags, CCB_FLAG_OPEN_WITH_VERSION )); - - - if (FlagOn( RelatedCcb->Flags, CCB_FLAG_OPEN_BY_ID | CCB_FLAG_OPEN_RELATIVE_BY_ID )) { - - SetFlag( CcbFlags, CCB_FLAG_OPEN_RELATIVE_BY_ID ); - } - } - - // - // Call our worker routine to complete the open. - // - - Status = CdCompleteFcbOpen( IrpContext, - IrpSp, - (*CurrentFcb)->Vcb, - CurrentFcb, - TypeOfOpen, - CcbFlags, - IrpSp->Parameters.Create.SecurityContext->DesiredAccess ); - } - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdOpenDirectoryFromPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN PIO_STACK_LOCATION IrpSp, - IN PVCB Vcb, - IN OUT PFCB *CurrentFcb, - IN PCD_NAME DirName, - IN BOOLEAN IgnoreCase, - IN BOOLEAN ShortNameMatch, - IN PPATH_ENTRY PathEntry, - IN BOOLEAN PerformUserOpen, - IN PCCB RelatedCcb OPTIONAL - ) - -/*++ - -Routine Description: - - This routine is called to open a directory where the directory was found - in the path table. This routine is called in the case where this is the - file to open for the user and where this is an intermediate node in the - full path to open. - - We first check that the desired access is legal for a directory. Then we - construct the FileId for this and do a check to see if it is the Fcb - Table. It is always possible that either it was created since or simply - wasn't in the prefix table at the time of the prefix table search. - Initialize the Fcb and store into the FcbTable if not present. - - Next we will add this to the prefix table of our parent if needed. - - Once we know that the new Fcb has been initialized then we move our pointer - in the tree down to this position. - - This routine does not own the Vcb lock on entry. We must be sure to release - it on exit. - -Arguments: - - IrpSp - Stack location for this request. - - Vcb - Vcb for this volume. - - CurrentFcb - On input this is the parent of the Fcb to open. On output we - store the Fcb for the file being opened. - - DirName - This is always the exact name used to reach this file. - - IgnoreCase - Indicates the type of case match for the open. - - ShortNameMatch - Indicates if we are opening via the short name. - - PathEntry - Path entry for the entry found. - - PerformUserOpen - TRUE if we are to open this for a user, FALSE otherwise. - - RelatedCcb - RelatedCcb for relative file object used to make this open. - -Return Value: - - NTSTATUS - Status indicating the result of the operation. - ---*/ - -{ - ULONG CcbFlags = 0; - FILE_ID FileId; - - BOOLEAN UnlockVcb = FALSE; - BOOLEAN FcbExisted; - - PFCB NextFcb; - PFCB ParentFcb = NULL; - - NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC uninitialized variable */ - - PAGED_CODE(); - - // - // Check for illegal access to this file. - // - - if (PerformUserOpen && - CdIllegalFcbAccess( IrpContext, - UserDirectoryOpen, - IrpSp->Parameters.Create.SecurityContext->DesiredAccess )) { - - return STATUS_ACCESS_DENIED; - } - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Check the related Ccb to see if this was an OpenByFileId. - // - - if (ARGUMENT_PRESENT( RelatedCcb ) && - FlagOn( RelatedCcb->Flags, CCB_FLAG_OPEN_BY_ID | CCB_FLAG_OPEN_RELATIVE_BY_ID )) { - - CcbFlags = CCB_FLAG_OPEN_RELATIVE_BY_ID; - } - - if (IgnoreCase) { - - SetFlag( CcbFlags, CCB_FLAG_IGNORE_CASE ); - } - - // - // Build the file Id for this file. - // - - FileId.QuadPart = 0; - CdSetFidPathTableOffset( FileId, PathEntry->PathTableOffset ); - CdFidSetDirectory( FileId ); - - // - // Lock the Vcb so we can examine the Fcb Table. - // - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - - // - // Get the Fcb for this directory. - // - - NextFcb = CdCreateFcb( IrpContext, FileId, CDFS_NTC_FCB_INDEX, &FcbExisted ); - - // - // If the Fcb was created here then initialize from the values in the - // path table entry. - // - - if (!FcbExisted) { - - CdInitializeFcbFromPathEntry( IrpContext, NextFcb, *CurrentFcb, PathEntry ); - } - - // - // Now try to acquire the new Fcb without waiting. We will reference - // the Fcb and retry with wait if unsuccessful. - // - - if (!CdAcquireFcbExclusive( IrpContext, NextFcb, TRUE )) { - - NextFcb->FcbReference += 1; - - CdUnlockVcb( IrpContext, Vcb ); - - CdReleaseFcb( IrpContext, *CurrentFcb ); - CdAcquireFcbExclusive( IrpContext, NextFcb, FALSE ); - CdAcquireFcbExclusive( IrpContext, *CurrentFcb, FALSE ); - - CdLockVcb( IrpContext, Vcb ); - NextFcb->FcbReference -= 1; - CdUnlockVcb( IrpContext, Vcb ); - - } else { - - // - // Unlock the Vcb and move down to this new Fcb. Remember that we still - // own the parent however. - // - - CdUnlockVcb( IrpContext, Vcb ); - } - - UnlockVcb = FALSE; - - ParentFcb = *CurrentFcb; - *CurrentFcb = NextFcb; - - // - // Store this name into the prefix table for the parent. - // - - if (ShortNameMatch) { - - // - // Make sure the exact case is always in the tree. - // - - CdInsertPrefix( IrpContext, - NextFcb, - DirName, - FALSE, - TRUE, - ParentFcb ); - - if (IgnoreCase) { - - CdInsertPrefix( IrpContext, - NextFcb, - DirName, - TRUE, - TRUE, - ParentFcb ); - } - - } else { - - // - // Make sure the exact case is always in the tree. - // - - CdInsertPrefix( IrpContext, - NextFcb, - &PathEntry->CdDirName, - FALSE, - FALSE, - ParentFcb ); - - if (IgnoreCase) { - - CdInsertPrefix( IrpContext, - NextFcb, - &PathEntry->CdCaseDirName, - TRUE, - FALSE, - ParentFcb ); - } - } - - // - // Release the parent Fcb at this point. - // - - CdReleaseFcb( IrpContext, ParentFcb ); - ParentFcb = NULL; - - // - // Call our worker routine to complete the open. - // - - if (PerformUserOpen) { - - Status = CdCompleteFcbOpen( IrpContext, - IrpSp, - Vcb, - CurrentFcb, - UserDirectoryOpen, - CcbFlags, - IrpSp->Parameters.Create.SecurityContext->DesiredAccess ); - } - - } finally { - - // - // Unlock the Vcb if held. - // - - if (UnlockVcb) { - - CdUnlockVcb( IrpContext, Vcb ); - } - - // - // Release the parent if held. - // - - if (ParentFcb != NULL) { - - CdReleaseFcb( IrpContext, ParentFcb ); - } - } - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdOpenFileFromFileContext ( - IN PIRP_CONTEXT IrpContext, - IN PIO_STACK_LOCATION IrpSp, - IN PVCB Vcb, - IN OUT PFCB *CurrentFcb, - IN PCD_NAME FileName, - IN BOOLEAN IgnoreCase, - IN BOOLEAN ShortNameMatch, - IN PFILE_ENUM_CONTEXT FileContext, - IN PCCB RelatedCcb OPTIONAL - ) - -/*++ - -Routine Description: - - This routine is called to open a file where the file was found in a directory scan. - This should only be for a file in the case since we will find the directories in the - path table. - - We first check that the desired access is legal for this file. Then we - construct the FileId for this and do a check to see if it is the Fcb - Table. It is always possible that either it was created since or simply - wasn't in the prefix table at the time of the prefix table search. - Initialize the Fcb and store into the FcbTable if not present. - - Next we will add this to the prefix table of our parent if needed. - - Once we know that the new Fcb has been initialized then we move our pointer - in the tree down to this position. - - This routine does not own the Vcb lock on entry. We must be sure to release - it on exit. - -Arguments: - - IrpSp - Stack location for this request. - - Vcb - Vcb for the current volume. - - CurrentFcb - On input this is the parent of the Fcb to open. On output we - store the Fcb for the file being opened. - - FileName - This is always the exact name used to reach this file. - - IgnoreCase - Indicates the type of case of CaseName above. - - ShortNameMatch - Indicates if we are opening via the short name. - - FileContext - This is the context used to find the file. - - RelatedCcb - RelatedCcb for relative file object used to make this open. - -Return Value: - - NTSTATUS - Status indicating the result of the operation. - ---*/ - -{ - ULONG CcbFlags = 0; - FILE_ID FileId; - - BOOLEAN UnlockVcb = FALSE; - BOOLEAN FcbExisted; - - PFCB NextFcb; - PFCB ParentFcb = NULL; - - NTSTATUS Status; - - PAGED_CODE(); - - // - // Check for illegal access to this file. - // - - if (CdIllegalFcbAccess( IrpContext, - UserFileOpen, - IrpSp->Parameters.Create.SecurityContext->DesiredAccess )) { - - return STATUS_ACCESS_DENIED; - } - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Check if a version number was used to open this file. - // - - if (FileName->VersionString.Length != 0) { - - SetFlag( CcbFlags, CCB_FLAG_OPEN_WITH_VERSION ); - } - - // - // Check the related Ccb to see if this was an OpenByFileId. - // - - if (ARGUMENT_PRESENT( RelatedCcb ) && - FlagOn( RelatedCcb->Flags, CCB_FLAG_OPEN_BY_ID | CCB_FLAG_OPEN_RELATIVE_BY_ID )) { - - SetFlag( CcbFlags, CCB_FLAG_OPEN_RELATIVE_BY_ID ); - } - - if (IgnoreCase) { - - SetFlag( CcbFlags, CCB_FLAG_IGNORE_CASE ); - } - - // - // Build the file Id for this file. We can use the path table offset from the - // parent and the directory offset from the dirent. - // - - CdSetFidPathTableOffset( FileId, CdQueryFidPathTableOffset( (*CurrentFcb)->FileId )); - CdSetFidDirentOffset( FileId, FileContext->InitialDirent->Dirent.DirentOffset ); - - // - // Lock the Vcb so we can examine the Fcb Table. - // - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - - // - // Get the Fcb for this file. - // - - NextFcb = CdCreateFcb( IrpContext, FileId, CDFS_NTC_FCB_DATA, &FcbExisted ); - - // - // If the Fcb was created here then initialize from the values in the - // dirent. - // - - if (!FcbExisted) { - - CdInitializeFcbFromFileContext( IrpContext, - NextFcb, - *CurrentFcb, - FileContext ); - } - - // - // Now try to acquire the new Fcb without waiting. We will reference - // the Fcb and retry with wait if unsuccessful. - // - - if (!CdAcquireFcbExclusive( IrpContext, NextFcb, TRUE )) { - - NextFcb->FcbReference += 1; - - CdUnlockVcb( IrpContext, Vcb ); - - CdReleaseFcb( IrpContext, *CurrentFcb ); - CdAcquireFcbExclusive( IrpContext, NextFcb, FALSE ); - CdAcquireFcbExclusive( IrpContext, *CurrentFcb, FALSE ); - - CdLockVcb( IrpContext, Vcb ); - NextFcb->FcbReference -= 1; - CdUnlockVcb( IrpContext, Vcb ); - - } else { - - // - // Unlock the Vcb and move down to this new Fcb. Remember that we still - // own the parent however. - // - - CdUnlockVcb( IrpContext, Vcb ); - } - - UnlockVcb = FALSE; - - ParentFcb = *CurrentFcb; - *CurrentFcb = NextFcb; - - // - // Store this name into the prefix table for the parent. - // - - - if (ShortNameMatch) { - - // - // Make sure the exact case is always in the tree. - // - - CdInsertPrefix( IrpContext, - NextFcb, - FileName, - FALSE, - TRUE, - ParentFcb ); - - if (IgnoreCase) { - - CdInsertPrefix( IrpContext, - NextFcb, - FileName, - TRUE, - TRUE, - ParentFcb ); - } - - // - // Insert this into the prefix table if we found this without - // using a version string. - // - - } else if (FileName->VersionString.Length == 0) { - - // - // Make sure the exact case is always in the tree. - // - - CdInsertPrefix( IrpContext, - NextFcb, - &FileContext->InitialDirent->Dirent.CdFileName, - FALSE, - FALSE, - ParentFcb ); - - if (IgnoreCase) { - - CdInsertPrefix( IrpContext, - NextFcb, - &FileContext->InitialDirent->Dirent.CdCaseFileName, - TRUE, - FALSE, - ParentFcb ); - } - } - - // - // Release the parent Fcb at this point. - // - - CdReleaseFcb( IrpContext, ParentFcb ); - ParentFcb = NULL; - - // - // Call our worker routine to complete the open. - // - - Status = CdCompleteFcbOpen( IrpContext, - IrpSp, - Vcb, - CurrentFcb, - UserFileOpen, - CcbFlags, - IrpSp->Parameters.Create.SecurityContext->DesiredAccess ); - - } finally { - - // - // Unlock the Vcb if held. - // - - if (UnlockVcb) { - - CdUnlockVcb( IrpContext, Vcb ); - } - - // - // Release the parent if held. - // - - if (ParentFcb != NULL) { - - CdReleaseFcb( IrpContext, ParentFcb ); - } - } - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdCompleteFcbOpen ( - IN PIRP_CONTEXT IrpContext, - PIO_STACK_LOCATION IrpSp, - IN PVCB Vcb, - IN OUT PFCB *CurrentFcb, - IN TYPE_OF_OPEN TypeOfOpen, - IN ULONG UserCcbFlags, - IN ACCESS_MASK DesiredAccess - ) - -/*++ - -Routine Description: - - This is the worker routine which takes an existing Fcb and completes - the open. We will do any necessary oplock checks and sharing checks. - Finally we will create the Ccb and update the file object and any - file object flags. - -Arguments: - - IrpSp - Stack location for the current request. - - Vcb - Vcb for the current volume. - - CurrentFcb - Address of pointer to Fcb to open. We clear this field if - we release the resource for this file. - - TypeOfOpen - Type of open for this request. - - UserCcbFlags - Flags to OR into the Ccb flags. - - DesiredAccess - Desired access for this open. - -Return Value: - - NTSTATUS - STATUS_SUCCESS if we complete this request, STATUS_PENDING if - the oplock package takes the Irp or SHARING_VIOLATION if there is a - sharing check conflict. - ---*/ - -{ - NTSTATUS Status; - NTSTATUS OplockStatus = STATUS_SUCCESS; - ULONG Information = FILE_OPENED; - - BOOLEAN LockVolume = FALSE; - - PFCB Fcb = *CurrentFcb; - PCCB Ccb; - - PAGED_CODE(); - - // - // Expand maximum allowed to something sensible for share access checking - // - - if (MAXIMUM_ALLOWED == DesiredAccess) { - - DesiredAccess = FILE_ALL_ACCESS & ~((TypeOfOpen != UserVolumeOpen ? - (FILE_WRITE_ATTRIBUTES | - FILE_WRITE_DATA | - FILE_WRITE_EA | - FILE_ADD_FILE | - FILE_ADD_SUBDIRECTORY | - FILE_APPEND_DATA) : 0) | - FILE_DELETE_CHILD | - DELETE | - WRITE_DAC ); - } - - // - // If this a volume open and the user wants to lock the volume then - // purge and lock the volume. - // - - if ((TypeOfOpen <= UserVolumeOpen) && - !FlagOn( IrpSp->Parameters.Create.ShareAccess, FILE_SHARE_READ )) { - - // - // If there are open handles then fail this immediately. - // - - if (Vcb->VcbCleanup != 0) { - - return STATUS_SHARING_VIOLATION; - } - - // - // If we can't wait then force this to be posted. - // - - if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - CdRaiseStatus( IrpContext, STATUS_CANT_WAIT ); - } - - LockVolume = TRUE; - - // - // Purge the volume and make sure all of the user references - // are gone. - // - - Status = CdPurgeVolume( IrpContext, Vcb, FALSE ); - - if (Status != STATUS_SUCCESS) { - - return Status; - } - - // - // Now force all of the delayed close operations to go away. - // - - CdFspClose( Vcb ); - - if (Vcb->VcbUserReference > CDFS_RESIDUAL_USER_REFERENCE) { - - return STATUS_SHARING_VIOLATION; - } - } - - // - // If the Fcb already existed then we need to check the oplocks and - // the share access. - // - - if (Fcb->FcbCleanup != 0) { - - // - // If this is a user file open then check whether there are any - // batch oplock. - // - - if (TypeOfOpen == UserFileOpen) { - - // - // Store the address of the Fcb for a possible teardown into - // the IrpContext. We will release this in the call to - // prepost the Irp. - // - - IrpContext->TeardownFcb = CurrentFcb; - - if (FsRtlCurrentBatchOplock( &Fcb->Oplock )) { - - // - // We remember if a batch oplock break is underway for the - // case where the sharing check fails. - // - - Information = FILE_OPBATCH_BREAK_UNDERWAY; - - OplockStatus = FsRtlCheckOplock( &Fcb->Oplock, - IrpContext->Irp, - IrpContext, - (PVOID)CdOplockComplete, /* ReactOS Change: GCC "assignment from incompatible pointer type" */ - (PVOID)CdPrePostIrp ); /* ReactOS Change: GCC "assignment from incompatible pointer type" */ - - if (OplockStatus == STATUS_PENDING) { - - return STATUS_PENDING; - } - } - - // - // Check the share access before breaking any exclusive oplocks. - // - - Status = IoCheckShareAccess( DesiredAccess, - IrpSp->Parameters.Create.ShareAccess, - IrpSp->FileObject, - &Fcb->ShareAccess, - FALSE ); - - if (!NT_SUCCESS( Status )) { - - return Status; - } - - // - // Now check that we can continue based on the oplock state of the - // file. - // - - OplockStatus = FsRtlCheckOplock( &Fcb->Oplock, - IrpContext->Irp, - IrpContext, - (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - (PVOID)CdPrePostIrp );/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - - if (OplockStatus == STATUS_PENDING) { - - return STATUS_PENDING; - } - - IrpContext->TeardownFcb = NULL; - - // - // Otherwise just do the sharing check. - // - - } else { - - Status = IoCheckShareAccess( DesiredAccess, - IrpSp->Parameters.Create.ShareAccess, - IrpSp->FileObject, - &Fcb->ShareAccess, - FALSE ); - - if (!NT_SUCCESS( Status )) { - - return Status; - } - } - } - - // - // Create the Ccb now. - // - - Ccb = CdCreateCcb( IrpContext, Fcb, UserCcbFlags ); - - // - // Update the share access. - // - - if (Fcb->FcbCleanup == 0) { - - IoSetShareAccess( DesiredAccess, - IrpSp->Parameters.Create.ShareAccess, - IrpSp->FileObject, - &Fcb->ShareAccess ); - - } else { - - IoUpdateShareAccess( IrpSp->FileObject, &Fcb->ShareAccess ); - } - - // - // Set the file object type. - // - - CdSetFileObject( IrpContext, IrpSp->FileObject, TypeOfOpen, Fcb, Ccb ); - - // - // Set the appropriate cache flags for a user file object. - // - - if (TypeOfOpen == UserFileOpen) { - - if (FlagOn( IrpSp->Parameters.Create.Options, FILE_NO_INTERMEDIATE_BUFFERING )) { - - SetFlag( IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING ); - - } else { - - SetFlag( IrpSp->FileObject->Flags, FO_CACHE_SUPPORTED ); - } - } - else if (TypeOfOpen == UserVolumeOpen) { - - SetFlag( IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING ); - } - - // - // Update the open and cleanup counts. Check the fast io state here. - // - - CdLockVcb( IrpContext, Vcb ); - - CdIncrementCleanupCounts( IrpContext, Fcb ); - CdIncrementReferenceCounts( IrpContext, Fcb, 1, 1 ); - - if (LockVolume) { - - Vcb->VolumeLockFileObject = IrpSp->FileObject; - SetFlag( Vcb->VcbState, VCB_STATE_LOCKED ); - } - - CdUnlockVcb( IrpContext, Vcb ); - - CdLockFcb( IrpContext, Fcb ); - - if (TypeOfOpen == UserFileOpen) { - - Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); - - } else { - - Fcb->IsFastIoPossible = FastIoIsNotPossible; - } - - CdUnlockFcb( IrpContext, Fcb ); - - // - // Show that we opened the file. - // - - IrpContext->Irp->IoStatus.Information = Information; - - // - // Point to the section object pointer in the non-paged Fcb. - // - - IrpSp->FileObject->SectionObjectPointer = &Fcb->FcbNonpaged->SegmentObject; - return OplockStatus; -} - - - - - diff --git a/reactos/drivers/filesystems/cdfs_new/devctrl.c b/reactos/drivers/filesystems/cdfs_new/devctrl.c deleted file mode 100755 index 7efebef13a4..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/devctrl.c +++ /dev/null @@ -1,196 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - DevCtrl.c - -Abstract: - - This module implements the File System Device Control routines for Cdfs - called by the dispatch driver. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_DEVCTRL) - -// -// Local support routines -// - -NTSTATUS -CdDevCtrlCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Contxt - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCommonDevControl) -#endif - - -NTSTATUS -CdCommonDevControl ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - -Arguments: - -Return Value: - ---*/ - -{ - NTSTATUS Status; - - TYPE_OF_OPEN TypeOfOpen; - PFCB Fcb; - PCCB Ccb; - - PIO_STACK_LOCATION IrpSp; - PIO_STACK_LOCATION NextIrpSp; - -// PVOID TargetBuffer = NULL; /* ReactOS Change: GCC unused variable */ - - PAGED_CODE(); - - // - // Extract and decode the file object. - // - - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - TypeOfOpen = CdDecodeFileObject( IrpContext, - IrpSp->FileObject, - &Fcb, - &Ccb ); - - // - // The only type of opens we accept are user volume opens. - // - - if (TypeOfOpen != UserVolumeOpen) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_READ_TOC) { - - // - // Verify the Vcb in this case to detect if the volume has changed. - // - - CdVerifyVcb( IrpContext, Fcb->Vcb ); - - // - // Handle the case of the disk type ourselves. - // - - } else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_DISK_TYPE) { - - // - // Verify the Vcb in this case to detect if the volume has changed. - // - - CdVerifyVcb( IrpContext, Fcb->Vcb ); - - // - // Check the size of the output buffer. - // - - if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( CDROM_DISK_DATA )) { - - CdCompleteRequest( IrpContext, Irp, STATUS_BUFFER_TOO_SMALL ); - return STATUS_BUFFER_TOO_SMALL; - } - - // - // Copy the data from the Vcb. - // - - ((PCDROM_DISK_DATA) Irp->AssociatedIrp.SystemBuffer)->DiskData = Fcb->Vcb->DiskFlags; - - Irp->IoStatus.Information = sizeof( CDROM_DISK_DATA ); - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - return STATUS_SUCCESS; - } - - // - // Get the next stack location, and copy over the stack parameter - // information. - // - - NextIrpSp = IoGetNextIrpStackLocation( Irp ); - - *NextIrpSp = *IrpSp; - - // - // Set up the completion routine - // - - IoSetCompletionRoutine( Irp, - CdDevCtrlCompletionRoutine, - NULL, - TRUE, - TRUE, - TRUE ); - - // - // Send the request. - // - - Status = IoCallDriver( IrpContext->Vcb->TargetDeviceObject, Irp ); - - // - // Cleanup our Irp Context. The driver has completed the Irp. - // - - CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdDevCtrlCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Contxt - ) - -{ - // - // Add the hack-o-ramma to fix formats. - // - - if (Irp->PendingReturned) { - - IoMarkIrpPending( Irp ); - } - - return STATUS_SUCCESS; - - UNREFERENCED_PARAMETER( DeviceObject ); - UNREFERENCED_PARAMETER( Contxt ); -} - - diff --git a/reactos/drivers/filesystems/cdfs_new/deviosup.c b/reactos/drivers/filesystems/cdfs_new/deviosup.c deleted file mode 100755 index bc737d5382c..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/deviosup.c +++ /dev/null @@ -1,3612 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - DevIoSup.c - -Abstract: - - This module implements the low lever disk read/write support for Cdfs. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_DEVIOSUP) - -// -// Local structure definitions -// - -// -// An array of these structures is passed to CdMultipleAsync describing -// a set of runs to execute in parallel. -// - -typedef struct _IO_RUN { - - // - // Disk offset to read from and number of bytes to read. These - // must be a multiple of 2048 and the disk offset is also a - // multiple of 2048. - // - - LONGLONG DiskOffset; - ULONG DiskByteCount; - - // - // Current position in user buffer. This is the final destination for - // this portion of the Io transfer. - // - - PVOID UserBuffer; - - // - // Buffer to perform the transfer to. If this is the same as the - // user buffer above then we are using the user's buffer. Otherwise - // we either allocated a temporary buffer or are using a different portion - // of the user's buffer. - // - // TransferBuffer - Read full sectors into this location. This can - // be a pointer into the user's buffer at the exact location the - // data should go. It can also be an earlier point in the user's - // buffer if the complete I/O doesn't start on a sector boundary. - // It may also be a pointer into an allocated buffer. - // - // TransferByteCount - Count of bytes to transfer to user's buffer. A - // value of zero indicates that we did do the transfer into the - // user's buffer directly. - // - // TransferBufferOffset - Offset in this buffer to begin the transfer - // to the user's buffer. - // - - PVOID TransferBuffer; - ULONG TransferByteCount; - ULONG TransferBufferOffset; - - // - // This is the Mdl describing the locked pages in memory. It may - // be allocated to describe the allocated buffer. Or it may be - // the Mdl in the originating Irp. The MdlOffset is the offset of - // the current buffer from the beginning of the buffer described by - // the Mdl below. If the TransferMdl is not the same as the Mdl - // in the user's Irp then we know we have allocated it. - // - - PMDL TransferMdl; - PVOID TransferVirtualAddress; - - // - // Associated Irp used to perform the Io. - // - - PIRP SavedIrp; - -} IO_RUN; -typedef IO_RUN *PIO_RUN; - -#define MAX_PARALLEL_IOS 5 - -// -// Local support routines -// - -BOOLEAN -CdPrepareBuffers ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PFCB Fcb, - IN PVOID UserBuffer, - IN ULONG UserBufferOffset, - IN LONGLONG StartingOffset, - IN ULONG ByteCount, - IN PIO_RUN IoRuns, - IN PULONG RunCount, - IN PULONG ThisByteCount - ); - -VOID -CdPrepareXABuffers ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PFCB Fcb, - IN PVOID UserBuffer, - IN ULONG UserBufferOffset, - IN LONGLONG StartingOffset, - IN ULONG ByteCount, - IN PIO_RUN IoRuns, - IN PULONG RunCount, - IN PULONG ThisByteCount - ); - -BOOLEAN -CdFinishBuffers ( - IN PIRP_CONTEXT IrpContext, - IN PIO_RUN IoRuns, - IN ULONG RunCount, - IN BOOLEAN FinalCleanup, - IN BOOLEAN SaveXABuffer - ); - -VOID -CdMultipleAsync ( - IN PIRP_CONTEXT IrpContext, - IN ULONG RunCount, - IN PIO_RUN IoRuns - ); - -VOID -CdMultipleXAAsync ( - IN PIRP_CONTEXT IrpContext, - IN ULONG RunCount, - IN PIO_RUN IoRuns, - IN PRAW_READ_INFO RawReads, - IN TRACK_MODE_TYPE TrackMode - ); - -VOID -CdSingleAsync ( - IN PIRP_CONTEXT IrpContext, - IN LONGLONG ByteOffset, - IN ULONG ByteCount - ); - -VOID -CdWaitSync ( - IN PIRP_CONTEXT IrpContext - ); - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdMultiSyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ); - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdMultiAsyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ); - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdSingleSyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ); - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdSingleAsyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ); - -VOID -CdReadAudioSystemFile ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG StartingOffset, - IN ULONG ByteCount, - IN PVOID SystemBuffer - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCreateUserMdl) -#pragma alloc_text(PAGE, CdMultipleAsync) -#pragma alloc_text(PAGE, CdMultipleXAAsync) -#pragma alloc_text(PAGE, CdNonCachedRead) -#pragma alloc_text(PAGE, CdNonCachedXARead) -#pragma alloc_text(PAGE, CdFinishBuffers) -#pragma alloc_text(PAGE, CdPerformDevIoCtrl) -#pragma alloc_text(PAGE, CdPrepareBuffers) -#pragma alloc_text(PAGE, CdReadAudioSystemFile) -#pragma alloc_text(PAGE, CdReadSectors) -#pragma alloc_text(PAGE, CdSingleAsync) -#pragma alloc_text(PAGE, CdWaitSync) -#endif - - -__inline -TRACK_MODE_TYPE -CdFileTrackMode ( - IN PFCB Fcb - ) - -/*++ - -Routine Description: - - This routine converts FCB XA file type flags to the track mode - used by the device drivers. - -Arguments: - - Fcb - Fcb representing the file to read. - -Return Value: - - TrackMode of the file represented by the Fcb. - ---*/ -{ - ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_MODE2FORM2_FILE | - FCB_STATE_MODE2_FILE | - FCB_STATE_DA_FILE )); - - if (FlagOn( Fcb->FcbState, FCB_STATE_MODE2FORM2_FILE )) { - - return XAForm2; - - } else if (FlagOn( Fcb->FcbState, FCB_STATE_DA_FILE )) { - - return CDDA; - - } - - // - // FCB_STATE_MODE2_FILE - // - - return YellowMode2; -} - - -NTSTATUS -CdNonCachedRead ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG StartingOffset, - IN ULONG ByteCount - ) - -/*++ - -Routine Description: - - This routine performs the non-cached reads to 'cooked' sectors (2048 bytes - per sector). This is done by performing the following in a loop. - - Fill in the IoRuns array for the next block of Io. - Send the Io to the device. - Perform any cleanup on the Io runs array. - - We will not do async Io to any request that generates non-aligned Io. - Also we will not perform async Io if it will exceed the size of our - IoRuns array. These should be the unusual cases but we will raise - or return CANT_WAIT in this routine if we detect this case. - -Arguments: - - Fcb - Fcb representing the file to read. - - StartingOffset - Logical offset in the file to read from. - - ByteCount - Number of bytes to read. - -Return Value: - - NTSTATUS - Status indicating the result of the operation. - ---*/ - -{ - NTSTATUS Status = STATUS_SUCCESS; - - IO_RUN IoRuns[MAX_PARALLEL_IOS]; - ULONG RunCount = 0; - ULONG CleanupRunCount = 0; - - PVOID UserBuffer; - ULONG UserBufferOffset = 0; - LONGLONG CurrentOffset = StartingOffset; - ULONG RemainingByteCount = ByteCount; - ULONG ThisByteCount; - - BOOLEAN Unaligned; - BOOLEAN FlushIoBuffers = FALSE; - BOOLEAN FirstPass = TRUE; - - PAGED_CODE(); - - // - // We want to make sure the user's buffer is locked in all cases. - // - - if (IrpContext->Irp->MdlAddress == NULL) { - - CdCreateUserMdl( IrpContext, ByteCount, TRUE ); - } - - CdMapUserBuffer( IrpContext, &UserBuffer); - - // - // Special case the root directory and path table for a music volume. - // - - if (FlagOn( Fcb->Vcb->VcbState, VCB_STATE_AUDIO_DISK ) && - ((SafeNodeType( Fcb ) == CDFS_NTC_FCB_INDEX) || - (SafeNodeType( Fcb ) == CDFS_NTC_FCB_PATH_TABLE))) { - - CdReadAudioSystemFile( IrpContext, - Fcb, - StartingOffset, - ByteCount, - UserBuffer ); - - return STATUS_SUCCESS; - } - - // - // Use a try-finally to perform the final cleanup. - // - - try { - - // - // Loop while there are more bytes to transfer. - // - - do { - - // - // Call prepare buffers to set up the next entries - // in the IoRuns array. Remember if there are any - // unaligned entries. This routine will raise CANT_WAIT - // if there are unaligned entries for an async request. - // - - RtlZeroMemory( IoRuns, sizeof( IoRuns )); - - Unaligned = CdPrepareBuffers( IrpContext, - IrpContext->Irp, - Fcb, - UserBuffer, - UserBufferOffset, - CurrentOffset, - RemainingByteCount, - IoRuns, - &CleanupRunCount, - &ThisByteCount ); - - - RunCount = CleanupRunCount; - - // - // If this is an async request and there aren't enough entries - // in the Io array then post the request. - // - - if ((ThisByteCount < RemainingByteCount) && - !FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - CdRaiseStatus( IrpContext, STATUS_CANT_WAIT ); - } - - // - // If the entire Io is contained in a single run then - // we can pass the Io down to the driver. Send the driver down - // and wait on the result if this is synchronous. - // - - if ((RunCount == 1) && !Unaligned && FirstPass) { - - CdSingleAsync( IrpContext, - IoRuns[0].DiskOffset, - IoRuns[0].DiskByteCount ); - - // - // No cleanup needed for the IoRuns array here. - // - - CleanupRunCount = 0; - - // - // Wait if we are synchronous, otherwise return - // - - if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - CdWaitSync( IrpContext ); - - Status = IrpContext->Irp->IoStatus.Status; - - // - // Our completion routine will free the Io context but - // we do want to return STATUS_PENDING. - // - - } else { - - ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO ); - Status = STATUS_PENDING; - } - - try_return( NOTHING ); - } - - // - // Otherwise we will perform multiple Io to read in the data. - // - - CdMultipleAsync( IrpContext, RunCount, IoRuns ); - - // - // If this is a synchronous request then perform any necessary - // post-processing. - // - - if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - // - // Wait for the request to complete. - // - - CdWaitSync( IrpContext ); - - Status = IrpContext->Irp->IoStatus.Status; - - // - // Exit this loop if there is an error. - // - - if (!NT_SUCCESS( Status )) { - - try_return( NOTHING ); - } - - // - // Perform post read operations on the IoRuns if - // necessary. - // - - if (Unaligned && - CdFinishBuffers( IrpContext, IoRuns, RunCount, FALSE, FALSE )) { - - FlushIoBuffers = TRUE; - } - - CleanupRunCount = 0; - - // - // Exit this loop if there are no more bytes to transfer - // or we have any error. - // - - RemainingByteCount -= ThisByteCount; - CurrentOffset += ThisByteCount; - UserBuffer = Add2Ptr( UserBuffer, ThisByteCount, PVOID ); - UserBufferOffset += ThisByteCount; - - // - // Otherwise this is an asynchronous request. Always return - // STATUS_PENDING. - // - - } else { - - ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO ); - CleanupRunCount = 0; - try_return( Status = STATUS_PENDING ); - break; - } - - FirstPass = FALSE; - } while (RemainingByteCount != 0); - - // - // Flush the hardware cache if we performed any copy operations. - // - - if (FlushIoBuffers) { - - KeFlushIoBuffers( IrpContext->Irp->MdlAddress, TRUE, FALSE ); - } - - try_exit: NOTHING; - } finally { - - // - // Perform final cleanup on the IoRuns if necessary. - // - - if (CleanupRunCount != 0) { - - CdFinishBuffers( IrpContext, IoRuns, CleanupRunCount, TRUE, FALSE ); - } - } - - return Status; -} - - -NTSTATUS -CdNonCachedXARead ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG StartingOffset, - IN ULONG ByteCount - ) - -/*++ - -Routine Description: - - This routine performs the non-cached reads for 'raw' sectors (2352 bytes - per sector). We also prepend a hard-coded RIFF header of 44 bytes to the file. - All of this is already reflected in the file size. - - We start by checking whether to prepend any portion of the RIFF header. Then we check - if the last raw sector read was from the beginning portion of this file, deallocating - that buffer if necessary. Finally we do the following in a loop. - - Fill the IoRuns array for the next block of Io. - Send the Io to the device driver. - Perform any cleanup necessary on the IoRuns array. - - We will not do any async request in this path. The request would have been - posted to a worker thread before getting to this point. - -Arguments: - - Fcb - Fcb representing the file to read. - - StartingOffset - Logical offset in the file to read from. - - ByteCount - Number of bytes to read. - -Return Value: - - NTSTATUS - Status indicating the result of the operation. - ---*/ - -{ - NTSTATUS Status = STATUS_SUCCESS; - - RIFF_HEADER LocalRiffHeader; - PRIFF_HEADER RiffHeader; - - RAW_READ_INFO RawReads[MAX_PARALLEL_IOS]; - IO_RUN IoRuns[MAX_PARALLEL_IOS]; - ULONG RunCount = 0; - ULONG CleanupRunCount = 0; - - PVOID UserBuffer; - ULONG UserBufferOffset = 0; - LONGLONG CurrentOffset = StartingOffset; - ULONG RemainingByteCount = ByteCount; - ULONG ThisByteCount; - - BOOLEAN TryingYellowbookMode2 = FALSE; - - TRACK_MODE_TYPE TrackMode; - - PAGED_CODE(); - - // - // We want to make sure the user's buffer is locked in all cases. - // - - if (IrpContext->Irp->MdlAddress == NULL) { - - CdCreateUserMdl( IrpContext, ByteCount, TRUE ); - } - - // - // The byte count was rounded up to a logical sector boundary. It has - // nothing to do with the raw sectors on disk. Limit the remaining - // byte count to file size. - // - - if (CurrentOffset + RemainingByteCount > Fcb->FileSize.QuadPart) { - - RemainingByteCount = (ULONG) (Fcb->FileSize.QuadPart - CurrentOffset); - } - - CdMapUserBuffer( IrpContext, &UserBuffer); - - // - // Use a try-finally to perform the final cleanup. - // - - try { - - // - // If the initial offset lies within the RIFF header then copy the - // necessary bytes to the user's buffer. - // - - if (CurrentOffset < sizeof( RIFF_HEADER )) { - - // - // Copy the appropriate RIFF header. - // - - if (FlagOn( Fcb->FcbState, FCB_STATE_DA_FILE )) { - - // - // Create the pseudo entries for a music disk. - // - - if (FlagOn( Fcb->Vcb->VcbState, VCB_STATE_AUDIO_DISK )) { - - PAUDIO_PLAY_HEADER AudioPlayHeader; - PTRACK_DATA TrackData; - ULONG SectorCount; - - AudioPlayHeader = (PAUDIO_PLAY_HEADER) &LocalRiffHeader; - TrackData = &Fcb->Vcb->CdromToc->TrackData[Fcb->XAFileNumber]; - - // - // Copy the data header into our local buffer. - // - - RtlCopyMemory( AudioPlayHeader, - CdAudioPlayHeader, - sizeof( AUDIO_PLAY_HEADER )); - - // - // Copy the serial number into the Id field. Also - // the track number in the TOC. - // - - AudioPlayHeader->DiskID = Fcb->Vcb->Vpb->SerialNumber; - AudioPlayHeader->TrackNumber = TrackData->TrackNumber; - - // - // TOC contains MSF (Minute/Second/Frame) addresses. This is very - // arcane, and we wind up having to bias around by the size of the - // leadins and other such silliness to find real live sector addrs. - // - // One frame == One sector. - // One second == 75 frames (winds up being a 44.1khz sample) - // - - // - // Fill in the address and length fields. - // - - AudioPlayHeader->TrackAddress[2] = TrackData->Address[1]; - AudioPlayHeader->TrackAddress[1] = TrackData->Address[2]; - AudioPlayHeader->TrackAddress[0] = TrackData->Address[3]; - - AudioPlayHeader->StartingSector = TrackData->Address[3]; - AudioPlayHeader->StartingSector += (TrackData->Address[2] * 75); - AudioPlayHeader->StartingSector += (TrackData->Address[1] * 60 * 75); - - // - // Subtract 2 seconds for the block number. - // - - AudioPlayHeader->StartingSector -= 150; - - // - // Go to the next track and find the starting point. - // - - TrackData = &Fcb->Vcb->CdromToc->TrackData[Fcb->XAFileNumber + 1]; - - AudioPlayHeader->SectorCount = TrackData->Address[3]; - AudioPlayHeader->SectorCount += (TrackData->Address[2] * 75); - AudioPlayHeader->SectorCount += (TrackData->Address[1] * 60 * 75); - - // - // Bias the sector count by 2 seconds. - // Check that the offset is at least two seconds. - // - - if (AudioPlayHeader->SectorCount < 150) { - - AudioPlayHeader->SectorCount = 0; - - } else { - - AudioPlayHeader->SectorCount -= 150; - } - - // - // Now compute the difference. If there is an error then use - // a length of zero. - // - - if (AudioPlayHeader->SectorCount < AudioPlayHeader->StartingSector) { - - AudioPlayHeader->SectorCount = 0; - - } else { - - AudioPlayHeader->SectorCount -= AudioPlayHeader->StartingSector; - } - - // - // Use the sector count to determine the MSF length. - // - - SectorCount = AudioPlayHeader->SectorCount; - - AudioPlayHeader->TrackLength[0] = (UCHAR) (SectorCount % 75); - SectorCount /= 75; - - AudioPlayHeader->TrackLength[1] = (UCHAR) (SectorCount % 60); - SectorCount /= 60; - - AudioPlayHeader->TrackLength[2] = (UCHAR) (SectorCount % 60); - - ThisByteCount = sizeof( RIFF_HEADER ) - (ULONG) CurrentOffset; - - RtlCopyMemory( UserBuffer, - Add2Ptr( AudioPlayHeader, - sizeof( RIFF_HEADER ) - ThisByteCount, - PCHAR ), - ThisByteCount ); - - // - // CD-XA CDDA - // - - } else { - - // - // The WAVE header format is actually much closer to an audio play - // header in format but we only need to modify the filesize fields. - // - - RiffHeader = &LocalRiffHeader; - - // - // Copy the data header into our local buffer and add the file size to it. - // - - RtlCopyMemory( RiffHeader, - CdXAAudioPhileHeader, - sizeof( RIFF_HEADER )); - - RiffHeader->ChunkSize += Fcb->FileSize.LowPart; - RiffHeader->RawSectors += Fcb->FileSize.LowPart; - - ThisByteCount = sizeof( RIFF_HEADER ) - (ULONG) CurrentOffset; - RtlCopyMemory( UserBuffer, - Add2Ptr( RiffHeader, - sizeof( RIFF_HEADER ) - ThisByteCount, - PCHAR ), - ThisByteCount ); - } - - // - // CD-XA non-audio - // - - } else { - - ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_MODE2_FILE | FCB_STATE_MODE2FORM2_FILE )); - - RiffHeader = &LocalRiffHeader; - - // - // Copy the data header into our local buffer and add the file size to it. - // - - RtlCopyMemory( RiffHeader, - CdXAFileHeader, - sizeof( RIFF_HEADER )); - - RiffHeader->ChunkSize += Fcb->FileSize.LowPart; - RiffHeader->RawSectors += Fcb->FileSize.LowPart; - - RiffHeader->Attributes = (USHORT) Fcb->XAAttributes; - RiffHeader->FileNumber = (UCHAR) Fcb->XAFileNumber; - - ThisByteCount = sizeof( RIFF_HEADER ) - (ULONG) CurrentOffset; - RtlCopyMemory( UserBuffer, - Add2Ptr( RiffHeader, - sizeof( RIFF_HEADER ) - ThisByteCount, - PCHAR ), - ThisByteCount ); - } - - // - // Adjust the starting offset and byte count to reflect that - // we copied over the RIFF bytes. - // - - UserBuffer = Add2Ptr( UserBuffer, ThisByteCount, PVOID ); - UserBufferOffset += ThisByteCount; - CurrentOffset += ThisByteCount; - RemainingByteCount -= ThisByteCount; - } - - // - // Set up the appropriate trackmode - // - - TrackMode = CdFileTrackMode(Fcb); - - // - // Loop while there are more bytes to transfer. - // - - while (RemainingByteCount != 0) { - - // - // Call prepare buffers to set up the next entries - // in the IoRuns array. Remember if there are any - // unaligned entries. If we're just retrying the previous - // runs with a different track mode, then don't do anything here. - // - - if (!TryingYellowbookMode2) { - - RtlZeroMemory( IoRuns, sizeof( IoRuns )); - RtlZeroMemory( RawReads, sizeof( RawReads )); - - CdPrepareXABuffers( IrpContext, - IrpContext->Irp, - Fcb, - UserBuffer, - UserBufferOffset, - CurrentOffset, - RemainingByteCount, - IoRuns, - &CleanupRunCount, - &ThisByteCount ); - } - - // - // Perform multiple Io to read in the data. Note that - // there may be no Io to do if we were able to use an - // existing buffer from the Vcb. - // - - if (CleanupRunCount != 0) { - - RunCount = CleanupRunCount; - - CdMultipleXAAsync( IrpContext, - RunCount, - IoRuns, - RawReads, - TrackMode ); - // - // Wait for the request to complete. - // - - CdWaitSync( IrpContext ); - - Status = IrpContext->Irp->IoStatus.Status; - - // - // Exit this loop if there is an error. - // - - if (!NT_SUCCESS( Status )) { - - if (!TryingYellowbookMode2 && - FlagOn( Fcb->FcbState, FCB_STATE_MODE2FORM2_FILE )) { - - // - // There are wacky cases where someone has mastered as CD-XA - // but the sectors they claim are Mode2Form2 are really, according - // to ATAPI devices, Yellowbook Mode2. We will try once more - // with these. Kodak PHOTO-CD has been observed to do this. - // - - TryingYellowbookMode2 = TRUE; - TrackMode = YellowMode2; - - // - // Clear our 'cumulative' error status value - // - - IrpContext->IoContext->Status = STATUS_SUCCESS; - - continue; - } - - try_return( NOTHING ); - } - - CleanupRunCount = 0; - - if (TryingYellowbookMode2) { - - // - // We succesfully got data when we tried switching the trackmode, - // so change the state of the FCB to remember that. - // - - SetFlag( Fcb->FcbState, FCB_STATE_MODE2_FILE ); - ClearFlag( Fcb->FcbState, FCB_STATE_MODE2FORM2_FILE ); - - TryingYellowbookMode2 = FALSE; - } - - // - // Perform post read operations on the IoRuns if - // necessary. - // - - CdFinishBuffers( IrpContext, IoRuns, RunCount, FALSE, TRUE ); - } - - // - // Adjust our loop variants. - // - - RemainingByteCount -= ThisByteCount; - CurrentOffset += ThisByteCount; - UserBuffer = Add2Ptr( UserBuffer, ThisByteCount, PVOID ); - UserBufferOffset += ThisByteCount; - } - - // - // Always flush the hardware cache. - // - - KeFlushIoBuffers( IrpContext->Irp->MdlAddress, TRUE, FALSE ); - - try_exit: NOTHING; - } finally { - - // - // Perform final cleanup on the IoRuns if necessary. - // - - if (CleanupRunCount != 0) { - - CdFinishBuffers( IrpContext, IoRuns, CleanupRunCount, TRUE, FALSE ); - } - } - - return Status; -} - - -BOOLEAN -CdReadSectors ( - IN PIRP_CONTEXT IrpContext, - IN LONGLONG StartingOffset, - IN ULONG ByteCount, - IN BOOLEAN ReturnError, - IN OUT PVOID Buffer, - IN PDEVICE_OBJECT TargetDeviceObject - ) - -/*++ - -Routine Description: - - This routine is called to transfer sectors from the disk to a - specified buffer. It is used for mount and volume verify operations. - - This routine is synchronous, it will not return until the operation - is complete or until the operation fails. - - The routine allocates an IRP and then passes this IRP to a lower - level driver. Errors may occur in the allocation of this IRP or - in the operation of the lower driver. - -Arguments: - - StartingOffset - Logical offset on the disk to start the read. This - must be on a sector boundary, no check is made here. - - ByteCount - Number of bytes to read. This is an integral number of - 2K sectors, no check is made here to confirm this. - - ReturnError - Indicates whether we should return TRUE or FALSE - to indicate an error or raise an error condition. This only applies - to the result of the IO. Any other error may cause a raise. - - Buffer - Buffer to transfer the disk data into. - - TargetDeviceObject - The device object for the volume to be read. - -Return Value: - - BOOLEAN - Depending on 'RaiseOnError' flag above. TRUE if operation - succeeded, FALSE otherwise. - ---*/ - -{ - NTSTATUS Status; - KEVENT Event; - PIRP Irp; - - PAGED_CODE(); - - // - // Initialize the event. - // - - KeInitializeEvent( &Event, NotificationEvent, FALSE ); - - // - // Attempt to allocate the IRP. If unsuccessful, raise - // STATUS_INSUFFICIENT_RESOURCES. - // - - Irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, - TargetDeviceObject, - Buffer, - ByteCount, - (PLARGE_INTEGER) &StartingOffset, - &Event, - &IrpContext->Irp->IoStatus ); - - if (Irp == NULL) { - - CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); - } - - // - // Ignore the change line (verify) for mount and verify requests - // - - SetFlag( IoGetNextIrpStackLocation( Irp )->Flags, SL_OVERRIDE_VERIFY_VOLUME ); - - // - // Send the request down to the driver. If an error occurs return - // it to the caller. - // - - Status = IoCallDriver( TargetDeviceObject, Irp ); - - // - // If the status was STATUS_PENDING then wait on the event. - // - - if (Status == STATUS_PENDING) { - - Status = KeWaitForSingleObject( &Event, - Executive, - KernelMode, - FALSE, - NULL ); - - // - // On a successful wait pull the status out of the IoStatus block. - // - - if (NT_SUCCESS( Status )) { - - Status = IrpContext->Irp->IoStatus.Status; - } - } - - // - // Check whether we should raise in the error case. - // - - if (!NT_SUCCESS( Status )) { - - if (!ReturnError) { - - CdNormalizeAndRaiseStatus( IrpContext, Status ); - } - - // - // We don't raise, but return FALSE to indicate an error. - // - - return FALSE; - - // - // The operation completed successfully. - // - - } else { - - return TRUE; - } -} - - -NTSTATUS -CdCreateUserMdl ( - IN PIRP_CONTEXT IrpContext, - IN ULONG BufferLength, - IN BOOLEAN RaiseOnError - ) - -/*++ - -Routine Description: - - This routine locks the specified buffer for read access (we only write into - the buffer). The file system requires this routine since it does not - ask the I/O system to lock its buffers for direct I/O. This routine - may only be called from the Fsd while still in the user context. - - This routine is only called if there is not already an Mdl. - -Arguments: - - BufferLength - Length of user buffer. - - RaiseOnError - Indicates if our caller wants this routine to raise on - an error condition. - -Return Value: - - NTSTATUS - Status from this routine. Error status only returned if - RaiseOnError is FALSE. - ---*/ - -{ - NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; - PMDL Mdl; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_IRP( IrpContext->Irp ); - ASSERT( IrpContext->Irp->MdlAddress == NULL ); - - // - // Allocate the Mdl, and Raise if we fail. - // - - Mdl = IoAllocateMdl( IrpContext->Irp->UserBuffer, - BufferLength, - FALSE, - FALSE, - IrpContext->Irp ); - - if (Mdl != NULL) { - - // - // Now probe the buffer described by the Irp. If we get an exception, - // deallocate the Mdl and return the appropriate "expected" status. - // - - try { - - MmProbeAndLockPages( Mdl, IrpContext->Irp->RequestorMode, IoWriteAccess ); - - Status = STATUS_SUCCESS; - - } except(EXCEPTION_EXECUTE_HANDLER) { - - Status = GetExceptionCode(); - - IoFreeMdl( Mdl ); - IrpContext->Irp->MdlAddress = NULL; - - if (!FsRtlIsNtstatusExpected( Status )) { - - Status = STATUS_INVALID_USER_BUFFER; - } - } - } - - // - // Check if we are to raise or return - // - - if (Status != STATUS_SUCCESS) { - - if (RaiseOnError) { - - CdRaiseStatus( IrpContext, Status ); - } - } - - // - // Return the status code. - // - - return Status; -} - - -NTSTATUS -CdPerformDevIoCtrl ( - IN PIRP_CONTEXT IrpContext, - IN ULONG IoControlCode, - IN PDEVICE_OBJECT Device, - OUT PVOID OutputBuffer OPTIONAL, - IN ULONG OutputBufferLength, - IN BOOLEAN InternalDeviceIoControl, - IN BOOLEAN OverrideVerify, - OUT PIO_STATUS_BLOCK Iosb OPTIONAL - ) - -/*++ - -Routine Description: - - This routine is called to perform DevIoCtrl functions internally within - the filesystem. We take the status from the driver and return it to our - caller. - -Arguments: - - IoControlCode - Code to send to driver. - - Device - This is the device to send the request to. - - OutPutBuffer - Pointer to output buffer. - - OutputBufferLength - Length of output buffer above. - - InternalDeviceIoControl - Indicates if this is an internal or external - Io control code. - - OverrideVerify - Indicates if we should tell the driver not to return - STATUS_VERIFY_REQUIRED for mount and verify. - - Iosb - If specified, we return the results of the operation here. - -Return Value: - - NTSTATUS - Status returned by next lower driver. - ---*/ - -{ - NTSTATUS Status; - PIRP Irp; - KEVENT Event; - IO_STATUS_BLOCK LocalIosb; - PIO_STATUS_BLOCK IosbToUse = &LocalIosb; - - PAGED_CODE(); - - // - // Check if the user gave us an Iosb. - // - - if (ARGUMENT_PRESENT( Iosb )) { - - IosbToUse = Iosb; - } - - IosbToUse->Status = 0; - IosbToUse->Information = 0; - - KeInitializeEvent( &Event, NotificationEvent, FALSE ); - - Irp = IoBuildDeviceIoControlRequest( IoControlCode, - Device, - NULL, - 0, - OutputBuffer, - OutputBufferLength, - InternalDeviceIoControl, - &Event, - IosbToUse ); - - if (Irp == NULL) { - - return STATUS_INSUFFICIENT_RESOURCES; - } - - if (OverrideVerify) { - - SetFlag( IoGetNextIrpStackLocation( Irp )->Flags, SL_OVERRIDE_VERIFY_VOLUME ); - } - - Status = IoCallDriver( Device, Irp ); - - // - // We check for device not ready by first checking Status - // and then if status pending was returned, the Iosb status - // value. - // - - if (Status == STATUS_PENDING) { - - (VOID) KeWaitForSingleObject( &Event, - Executive, - KernelMode, - FALSE, - (PLARGE_INTEGER)NULL ); - - Status = IosbToUse->Status; - } - - ASSERT( !(OverrideVerify && (STATUS_VERIFY_REQUIRED == Status))); - - return Status; -} - - -// -// Local support routine -// - -BOOLEAN -CdPrepareBuffers ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PFCB Fcb, - IN PVOID UserBuffer, - IN ULONG UserBufferOffset, - IN LONGLONG StartingOffset, - IN ULONG ByteCount, - IN PIO_RUN IoRuns, - IN PULONG RunCount, - IN PULONG ThisByteCount - ) - -/*++ - -Routine Description: - - This routine is the worker routine which looks up each run of an IO - request and stores an entry for it in the IoRuns array. If the run - begins on an unaligned disk boundary then we will allocate a buffer - and Mdl for the unaligned portion and put it in the IoRuns entry. - - This routine will raise CANT_WAIT if an unaligned transfer is encountered - and this request can't wait. - -Arguments: - - Irp - Originating Irp for this request. - - Fcb - This is the Fcb for this data stream. It may be a file, directory, - path table or the volume file. - - UserBuffer - Current position in the user's buffer. - - UserBufferOffset - Offset from the start of the original user buffer. - - StartingOffset - Offset in the stream to begin the read. - - ByteCount - Number of bytes to read. We will fill the IoRuns array up - to this point. We will stop early if we exceed the maximum number - of parallel Ios we support. - - IoRuns - Pointer to the IoRuns array. The entire array is zeroes when - this routine is called. - - RunCount - Number of entries in the IoRuns array filled here. - - ThisByteCount - Number of bytes described by the IoRun entries. Will - not exceed the ByteCount passed in. - -Return Value: - - BOOLEAN - TRUE if one of the entries in an unaligned buffer (provided - this is synchronous). FALSE otherwise. - ---*/ - -{ - BOOLEAN FoundUnaligned = FALSE; - PIO_RUN ThisIoRun = IoRuns; - - // - // Following indicate where we are in the current transfer. Current - // position in the file and number of bytes yet to transfer from - // this position. - // - - ULONG RemainingByteCount = ByteCount; - LONGLONG CurrentFileOffset = StartingOffset; - - // - // Following indicate the state of the user's buffer. We have - // the destination of the next transfer and its offset in the - // buffer. We also have the next available position in the buffer - // available for a scratch buffer. We will align this up to a sector - // boundary. - // - - PVOID CurrentUserBuffer = UserBuffer; - ULONG CurrentUserBufferOffset = UserBufferOffset; - - PVOID ScratchUserBuffer = UserBuffer; - ULONG ScratchUserBufferOffset = UserBufferOffset; - - // - // The following is the next contiguous bytes on the disk to - // transfer. Read from the allocation package. - // - - LONGLONG DiskOffset; - ULONG CurrentByteCount; - - PAGED_CODE(); - - // - // Initialize the RunCount and ByteCount. - // - - *RunCount = 0; - *ThisByteCount = 0; - - // - // Loop while there are more bytes to process or there are - // available entries in the IoRun array. - // - - while (TRUE) { - - *RunCount += 1; - - // - // Initialize the current position in the IoRuns array. - // Find the user's buffer for this portion of the transfer. - // - - ThisIoRun->UserBuffer = CurrentUserBuffer; - - // - // Find the allocation information for the current offset in the - // stream. - // - - CdLookupAllocation( IrpContext, - Fcb, - CurrentFileOffset, - &DiskOffset, - &CurrentByteCount ); - - // - // Limit ourselves to the data requested. - // - - if (CurrentByteCount > RemainingByteCount) { - - CurrentByteCount = RemainingByteCount; - } - - // - // Handle the case where this is an unaligned transfer. The - // following must all be true for this to be an aligned transfer. - // - // Disk offset on a 2048 byte boundary (Start of transfer) - // - // Byte count is a multiple of 2048 (Length of transfer) - // - // Current buffer offset is also on a 2048 byte boundary. - // - // If the ByteCount is at least one sector then do the - // unaligned transfer only for the tail. We can use the - // user's buffer for the aligned portion. - // - - if (FlagOn( (ULONG) DiskOffset, SECTOR_MASK ) || - FlagOn( CurrentUserBufferOffset, SECTOR_MASK ) || - (FlagOn( (ULONG) CurrentByteCount, SECTOR_MASK ) && - (CurrentByteCount < SECTOR_SIZE))) { - - // - // If we can't wait then raise. - // - - if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - CdRaiseStatus( IrpContext, STATUS_CANT_WAIT ); - } - - // - // Remember the offset and the number of bytes out of - // the transfer buffer to copy into the user's buffer. - // We will truncate the current read to end on a sector - // boundary. - // - - ThisIoRun->TransferBufferOffset = SectorOffset( DiskOffset ); - - // - // Make sure this transfer ends on a sector boundary. - // - - ThisIoRun->DiskOffset = LlSectorTruncate( DiskOffset ); - - // - // Check if we can use a free portion of the user's buffer. - // If we can copy the bytes to an earlier portion of the - // buffer then read into that location and slide the bytes - // up. - // - // We can use the user's buffer if: - // - // The temporary location in the buffer is before the - // final destination. - // - // There is at least one sector of data to read. - // - - if ((ScratchUserBufferOffset + ThisIoRun->TransferBufferOffset < CurrentUserBufferOffset) && - (ThisIoRun->TransferBufferOffset + CurrentByteCount >= SECTOR_SIZE)) { - - ThisIoRun->DiskByteCount = SectorTruncate( ThisIoRun->TransferBufferOffset + CurrentByteCount ); - CurrentByteCount = ThisIoRun->DiskByteCount - ThisIoRun->TransferBufferOffset; - ThisIoRun->TransferByteCount = CurrentByteCount; - - // - // Point to the user's buffer and Mdl for this transfer. - // - - ThisIoRun->TransferBuffer = ScratchUserBuffer; - ThisIoRun->TransferMdl = Irp->MdlAddress; - ThisIoRun->TransferVirtualAddress = Add2Ptr( Irp->UserBuffer, - ScratchUserBufferOffset, - PVOID ); - - ScratchUserBuffer = Add2Ptr( ScratchUserBuffer, - ThisIoRun->DiskByteCount, - PVOID ); - - ScratchUserBufferOffset += ThisIoRun->DiskByteCount; - - // - // Otherwise we need to allocate an auxilary buffer for the next sector. - // - - } else { - - // - // Read up to a page containing the partial data - // - - ThisIoRun->DiskByteCount = SectorAlign( ThisIoRun->TransferBufferOffset + CurrentByteCount ); - - if (ThisIoRun->DiskByteCount > PAGE_SIZE) { - - ThisIoRun->DiskByteCount = PAGE_SIZE; - } - - if (ThisIoRun->TransferBufferOffset + CurrentByteCount > ThisIoRun->DiskByteCount) { - - CurrentByteCount = ThisIoRun->DiskByteCount - ThisIoRun->TransferBufferOffset; - } - - ThisIoRun->TransferByteCount = CurrentByteCount; - - // - // Allocate a buffer for the non-aligned transfer. - // - - ThisIoRun->TransferBuffer = FsRtlAllocatePoolWithTag( CdNonPagedPool, PAGE_SIZE, TAG_IO_BUFFER ); - - // - // Allocate and build the Mdl to describe this buffer. - // - - ThisIoRun->TransferMdl = IoAllocateMdl( ThisIoRun->TransferBuffer, - PAGE_SIZE, - FALSE, - FALSE, - NULL ); - - ThisIoRun->TransferVirtualAddress = ThisIoRun->TransferBuffer; - - if (ThisIoRun->TransferMdl == NULL) { - - IrpContext->Irp->IoStatus.Information = 0; - CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); - } - - MmBuildMdlForNonPagedPool( ThisIoRun->TransferMdl ); - } - - // - // Remember we found an unaligned transfer. - // - - FoundUnaligned = TRUE; - - // - // Otherwise we use the buffer and Mdl from the original request. - // - - } else { - - // - // Truncate the read length to a sector-aligned value. We know - // the length must be at least one sector or we wouldn't be - // here now. - // - - CurrentByteCount = SectorTruncate( CurrentByteCount ); - - // - // Read these sectors from the disk. - // - - ThisIoRun->DiskOffset = DiskOffset; - ThisIoRun->DiskByteCount = CurrentByteCount; - - // - // Use the user's buffer and Mdl as our transfer buffer - // and Mdl. - // - - ThisIoRun->TransferBuffer = CurrentUserBuffer; - ThisIoRun->TransferMdl = Irp->MdlAddress; - ThisIoRun->TransferVirtualAddress = Add2Ptr( Irp->UserBuffer, - CurrentUserBufferOffset, - PVOID ); - - ScratchUserBuffer = Add2Ptr( CurrentUserBuffer, - CurrentByteCount, - PVOID ); - - ScratchUserBufferOffset += CurrentByteCount; - } - - // - // Update our position in the transfer and the RunCount and - // ByteCount for the user. - // - - RemainingByteCount -= CurrentByteCount; - - // - // Break out if no more positions in the IoRuns array or - // we have all of the bytes accounted for. - // - - *ThisByteCount += CurrentByteCount; - - if ((RemainingByteCount == 0) || (*RunCount == MAX_PARALLEL_IOS)) { - - break; - } - - // - // Update our pointers for the user's buffer. - // - - ThisIoRun += 1; - CurrentUserBuffer = Add2Ptr( CurrentUserBuffer, CurrentByteCount, PVOID ); - CurrentUserBufferOffset += CurrentByteCount; - CurrentFileOffset += CurrentByteCount; - } - - return FoundUnaligned; -} - - -// -// Local support routine -// - -VOID -CdPrepareXABuffers ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PFCB Fcb, - IN PVOID UserBuffer, - IN ULONG UserBufferOffset, - IN LONGLONG StartingOffset, - IN ULONG ByteCount, - IN PIO_RUN IoRuns, - IN PULONG RunCount, - IN PULONG ThisByteCount - ) - -/*++ - -Routine Description: - - This routine is the worker routine which looks up the individual runs - of an IO request and stores an entry for it in the IoRuns array. The - worker routine is for XA files where we need to convert the raw offset - in the file to logical cooked sectors. We store one raw sector in - the Vcb. If the current read is to that sector then we can simply copy - whatever bytes are needed from that sector. - -Arguments: - - Irp - Originating Irp for this request. - - Fcb - This is the Fcb for this data stream. It must be a data stream. - - UserBuffer - Current position in the user's buffer. - - UserBufferOffset - Offset of this buffer from the beginning of the user's - buffer for the original request. - - StartingOffset - Offset in the stream to begin the read. - - ByteCount - Number of bytes to read. We will fill the IoRuns array up - to this point. We will stop early if we exceed the maximum number - of parallel Ios we support. - - IoRuns - Pointer to the IoRuns array. The entire array is zeroes when - this routine is called. - - RunCount - Number of entries in the IoRuns array filled here. - - ThisByteCount - Number of bytes described by the IoRun entries. Will - not exceed the ByteCount passed in. - -Return Value: - - None - ---*/ - -{ - PIO_RUN ThisIoRun = IoRuns; - BOOLEAN PerformedCopy; - - // - // The following deal with where we are in the range of raw sectors. - // Note that we will bias the input file offset by the RIFF header - // to deal directly with the raw sectors. - // - - ULONG RawSectorOffset; - ULONG RemainingRawByteCount = ByteCount; - LONGLONG CurrentRawOffset = StartingOffset - sizeof( RIFF_HEADER ); - - // - // The following is the offset into the cooked sectors for the file. - // - - LONGLONG CurrentCookedOffset; - ULONG RemainingCookedByteCount; - - // - // Following indicate the state of the user's buffer. We have - // the destination of the next transfer and its offset in the - // buffer. We also have the next available position in the buffer - // available for a scratch buffer. - // - - PVOID CurrentUserBuffer = UserBuffer; - ULONG CurrentUserBufferOffset = UserBufferOffset; - - PVOID ScratchUserBuffer = UserBuffer; - ULONG ScratchUserBufferOffset = UserBufferOffset; - BOOLEAN RoundScratchBuffer = TRUE; - - // - // The following is the next contiguous bytes on the disk to - // transfer. These are represented by cooked byte offset and length. - // We also compute the number of raw bytes in the current transfer. - // - - LONGLONG DiskOffset; - ULONG CurrentCookedByteCount; - ULONG CurrentRawByteCount; - - PAGED_CODE(); - - // - // We need to maintain our position as we walk through the sectors on the disk. - // We keep separate values for the cooked offset as well as the raw offset. - // These are initialized on sector boundaries and we move through these - // the file sector-by-sector. - // - // Try to do 32-bit math. - // - - if (((PLARGE_INTEGER) &CurrentRawOffset)->HighPart == 0) { - - // - // Prefix/fast: Note that the following are safe since we only - // take this path for 32bit offsets. - // - - CurrentRawOffset = (LONGLONG) ((ULONG) CurrentRawOffset / RAW_SECTOR_SIZE); - - CurrentCookedOffset = (LONGLONG) ((ULONG) CurrentRawOffset << SECTOR_SHIFT ); - - CurrentRawOffset = (LONGLONG) ((ULONG) CurrentRawOffset * RAW_SECTOR_SIZE); - - // - // Otherwise we need to do 64-bit math (sigh). - // - - } else { - - CurrentRawOffset /= RAW_SECTOR_SIZE; - - CurrentCookedOffset = CurrentRawOffset << SECTOR_SHIFT; - - CurrentRawOffset *= RAW_SECTOR_SIZE; - } - - // - // Now compute the full number of sectors to be read. Count all of the raw - // sectors that need to be read and convert to cooked bytes. - // - - RawSectorOffset = (ULONG) ( StartingOffset - CurrentRawOffset) - sizeof( RIFF_HEADER ); - CurrentRawByteCount = (RawSectorOffset + RemainingRawByteCount + RAW_SECTOR_SIZE - 1) / RAW_SECTOR_SIZE; - - RemainingCookedByteCount = CurrentRawByteCount << SECTOR_SHIFT; - - // - // Initialize the RunCount and ByteCount. - // - - *RunCount = 0; - *ThisByteCount = 0; - - // - // Loop while there are more bytes to process or there are - // available entries in the IoRun array. - // - - while (TRUE) { - - PerformedCopy = FALSE; - *RunCount += 1; - - // - // Round the scratch buffer up to a sector boundary for alignment. - // - - if (RoundScratchBuffer) { - - if (SectorOffset( ScratchUserBuffer ) != 0) { - - CurrentRawByteCount = SECTOR_SIZE - SectorOffset( ScratchUserBuffer ); - - ScratchUserBuffer = Add2Ptr( ScratchUserBuffer, - CurrentRawByteCount, - PVOID ); - - ScratchUserBufferOffset += CurrentRawByteCount; - } - - RoundScratchBuffer = FALSE; - } - - // - // Initialize the current position in the IoRuns array. Find the - // eventual destination in the user's buffer for this portion of the transfer. - // - - ThisIoRun->UserBuffer = CurrentUserBuffer; - - // - // Find the allocation information for the current offset in the - // stream. - // - - CdLookupAllocation( IrpContext, - Fcb, - CurrentCookedOffset, - &DiskOffset, - &CurrentCookedByteCount ); - // - // Maybe we got lucky and this is the same sector as in the - // Vcb. - // - - if (DiskOffset == Fcb->Vcb->XADiskOffset) { - - // - // We will perform safe synchronization. Check again that - // this is the correct sector. - // - - CdLockVcb( IrpContext, Fcb->Vcb ); - - if ((DiskOffset == Fcb->Vcb->XADiskOffset) && - (Fcb->Vcb->XASector != NULL)) { - - // - // Copy any bytes we can from the current sector. - // - - CurrentRawByteCount = RAW_SECTOR_SIZE - RawSectorOffset; - - // - // Check whether we don't go to the end of the sector. - // - - if (CurrentRawByteCount > RemainingRawByteCount) { - - CurrentRawByteCount = RemainingRawByteCount; - } - - RtlCopyMemory( CurrentUserBuffer, - Add2Ptr( Fcb->Vcb->XASector, RawSectorOffset, PCHAR ), - CurrentRawByteCount ); - - CdUnlockVcb( IrpContext, Fcb->Vcb ); - - // - // Adjust the run count and pointer in the IoRuns array - // to show that we didn't use a position. - // - - *RunCount -= 1; - ThisIoRun -= 1; - - // - // Remember that we performed a copy operation and update - // the next available position in the scratch buffer. - // - - PerformedCopy = TRUE; - - ScratchUserBuffer = Add2Ptr( ScratchUserBuffer, - CurrentRawByteCount, - PVOID ); - - ScratchUserBufferOffset += CurrentRawByteCount; - - CurrentCookedByteCount = SECTOR_SIZE; - - // - // Set the flag indicating we want to round the scratch buffer - // to a sector boundary. - // - - RoundScratchBuffer = TRUE; - - } else { - - // - // The safe test showed no available buffer. Drop down to common code to - // perform the Io. - // - - CdUnlockVcb( IrpContext, Fcb->Vcb ); - } - } - - // - // No work in this pass if we did a copy operation. - // - - if (!PerformedCopy) { - - // - // Limit ourselves by the number of remaining cooked bytes. - // - - if (CurrentCookedByteCount > RemainingCookedByteCount) { - - CurrentCookedByteCount = RemainingCookedByteCount; - } - - ThisIoRun->DiskOffset = DiskOffset; - ThisIoRun->TransferBufferOffset = RawSectorOffset; - - // - // We will always need to perform copy operations for XA files. - // We allocate an auxillary buffer to read the start of the - // transfer. Then we can use a range of the user's buffer to - // perform the next range of the transfer. Finally we may - // need to allocate a buffer for the tail of the transfer. - // - // We can use the user's buffer (at the current scratch buffer) if the - // following are true: - // - // If we are to store the beginning of the raw sector in the user's buffer. - // The current scratch buffer precedes the destination in the user's buffer - // (and hence also lies within it) - // There are enough bytes remaining in the buffer for at least one - // raw sector. - // - - if ((RawSectorOffset == 0) && - (ScratchUserBufferOffset <= CurrentUserBufferOffset) && - (CurrentUserBufferOffset - ScratchUserBufferOffset + RemainingRawByteCount >= RAW_SECTOR_SIZE)) { - - // - // We can use the scratch buffer. We must ensure we don't send down reads - // greater than the device can handle, since the driver is unable to split - // raw requests. - // - - if (CurrentCookedByteCount <= Fcb->Vcb->MaximumTransferRawSectors * SECTOR_SIZE) { - - CurrentRawByteCount = (SectorAlign( CurrentCookedByteCount) >> SECTOR_SHIFT) * RAW_SECTOR_SIZE; - - } else { - - CurrentCookedByteCount = Fcb->Vcb->MaximumTransferRawSectors * SECTOR_SIZE; - CurrentRawByteCount = Fcb->Vcb->MaximumTransferRawSectors * RAW_SECTOR_SIZE; - } - - // - // Now make sure we are within the page transfer limit. - // - - while (ADDRESS_AND_SIZE_TO_SPAN_PAGES(ScratchUserBuffer, RawSectorAlign( CurrentRawByteCount)) > - Fcb->Vcb->MaximumPhysicalPages ) { - - CurrentRawByteCount -= RAW_SECTOR_SIZE; - CurrentCookedByteCount -= SECTOR_SIZE; - } - - // - // Trim the number of bytes to read if it won't fit into the current buffer. Take - // account of the fact that we must read in whole raw sector multiples. - // - - while ( RawSectorAlign( CurrentRawByteCount) > - (CurrentUserBufferOffset - ScratchUserBufferOffset + RemainingRawByteCount) ) { - - CurrentRawByteCount -= RAW_SECTOR_SIZE; - CurrentCookedByteCount -= SECTOR_SIZE; - } - - // - // Now trim the maximum number of raw bytes to the remaining bytes. - // - - if (CurrentRawByteCount > RemainingRawByteCount) { - - CurrentRawByteCount = RemainingRawByteCount; - } - - // - // Update the IO run array. We point to the scratch buffer as - // well as the buffer and Mdl in the original Irp. - // - - ThisIoRun->DiskByteCount = SectorAlign( CurrentCookedByteCount); - - // - // Store the number of bytes which we actually care about from this transfer - // - - ThisIoRun->TransferByteCount = CurrentRawByteCount; - - // - // Point to the user's buffer and Mdl for this transfer. - // - - ThisIoRun->TransferBuffer = ScratchUserBuffer; - ThisIoRun->TransferMdl = Irp->MdlAddress; - ThisIoRun->TransferVirtualAddress = Add2Ptr( Irp->UserBuffer, - ScratchUserBufferOffset, - PVOID); - // - // Update the scratch buffer pointer. Note that since the underlying - // driver stack will always transfer in multiples of raw sectors, - // we must round up here rather than simply advancing by the length of the - // of the data which we actually care about. - // - - ScratchUserBuffer = Add2Ptr( ScratchUserBuffer, - RawSectorAlign( CurrentRawByteCount), - PVOID ); - - ScratchUserBufferOffset += RawSectorAlign( CurrentRawByteCount);; - - // - // Set the flag indicating we want to round the scratch buffer - // to a cooked sector boundary. - // - - RoundScratchBuffer = TRUE; - - } else { - - // - // We need to determine the number of bytes to transfer and the - // offset into this page to begin the transfer. - // - // We will transfer only one raw sector. - // - - ThisIoRun->DiskByteCount = SECTOR_SIZE; - - CurrentCookedByteCount = SECTOR_SIZE; - - ThisIoRun->TransferByteCount = RAW_SECTOR_SIZE - RawSectorOffset; - ThisIoRun->TransferBufferOffset = RawSectorOffset; - - if (ThisIoRun->TransferByteCount > RemainingRawByteCount) { - - ThisIoRun->TransferByteCount = RemainingRawByteCount; - } - - CurrentRawByteCount = ThisIoRun->TransferByteCount; - - // - // We need to allocate an auxillary buffer. We will allocate - // a single page. Then we will build an Mdl to describe the buffer. - // - - ThisIoRun->TransferBuffer = FsRtlAllocatePoolWithTag( CdNonPagedPool, PAGE_SIZE, TAG_IO_BUFFER ); - - // - // Allocate and build the Mdl to describe this buffer. - // - - ThisIoRun->TransferMdl = IoAllocateMdl( ThisIoRun->TransferBuffer, - PAGE_SIZE, - FALSE, - FALSE, - NULL ); - - ThisIoRun->TransferVirtualAddress = ThisIoRun->TransferBuffer; - - if (ThisIoRun->TransferMdl == NULL) { - - IrpContext->Irp->IoStatus.Information = 0; - CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); - } - - MmBuildMdlForNonPagedPool( ThisIoRun->TransferMdl ); - } - } - - // - // Update the byte count for our caller. - // - - RemainingRawByteCount -= CurrentRawByteCount; - *ThisByteCount += CurrentRawByteCount; - - // - // Break out if no more positions in the IoRuns array or - // we have all of the bytes accounted for. - // - - if ((RemainingRawByteCount == 0) || (*RunCount == MAX_PARALLEL_IOS)) { - - break; - } - - // - // Update our local pointers to allow for the current range of bytes. - // - - ThisIoRun += 1; - - CurrentUserBuffer = Add2Ptr( CurrentUserBuffer, CurrentRawByteCount, PVOID ); - CurrentUserBufferOffset += CurrentRawByteCount; - - RawSectorOffset = 0; - - CurrentCookedOffset += CurrentCookedByteCount; - RemainingCookedByteCount -= CurrentCookedByteCount; - } - - return; -} - - -// -// Local support routine -// - -BOOLEAN -CdFinishBuffers ( - IN PIRP_CONTEXT IrpContext, - IN PIO_RUN IoRuns, - IN ULONG RunCount, - IN BOOLEAN FinalCleanup, - IN BOOLEAN SaveXABuffer - ) - -/*++ - -Routine Description: - - This routine is called to perform any data transferred required for - unaligned Io or to perform the final cleanup of the IoRuns array. - - In all cases this is where we will deallocate any buffer and mdl - allocated to perform the unaligned transfer. If this is not the - final cleanup then we also transfer the bytes to the user buffer - and flush the hardware cache. - - We walk backwards through the run array because we may be shifting data - in the user's buffer. Typical case is where we allocated a buffer for - the first part of a read and then used the user's buffer for the - next section (but stored it at the beginning of the buffer. - -Arguments: - - IoRuns - Pointer to the IoRuns array. - - RunCount - Number of entries in the IoRuns array filled here. - - FinalCleanup - Indicates if we should be deallocating temporary buffers - (TRUE) or transferring bytes for a unaligned transfers and - deallocating the buffers (FALSE). Flush the system cache if - transferring data. - - SaveXABuffer - TRUE if we should try to save an XA buffer, FALSE otherwise - -Return Value: - - BOOLEAN - TRUE if this request needs the Io buffers to be flushed, FALSE otherwise. - ---*/ - -{ - BOOLEAN FlushIoBuffers = FALSE; - - ULONG RemainingEntries = RunCount; - PIO_RUN ThisIoRun = &IoRuns[RunCount - 1]; - PVCB Vcb; - - PAGED_CODE(); - - // - // Walk through each entry in the IoRun array. - // - - while (RemainingEntries != 0) { - - // - // We only need to deal with the case of an unaligned transfer. - // - - if (ThisIoRun->TransferByteCount != 0) { - - // - // If not the final cleanup then transfer the data to the - // user's buffer and remember that we will need to flush - // the user's buffer to memory. - // - - if (!FinalCleanup) { - - // - // If we are shifting in the user's buffer then use - // MoveMemory. - // - - if (ThisIoRun->TransferMdl == IrpContext->Irp->MdlAddress) { - - RtlMoveMemory( ThisIoRun->UserBuffer, - Add2Ptr( ThisIoRun->TransferBuffer, - ThisIoRun->TransferBufferOffset, - PVOID ), - ThisIoRun->TransferByteCount ); - - } else { - - RtlCopyMemory( ThisIoRun->UserBuffer, - Add2Ptr( ThisIoRun->TransferBuffer, - ThisIoRun->TransferBufferOffset, - PVOID ), - ThisIoRun->TransferByteCount ); - } - - FlushIoBuffers = TRUE; - } - - // - // Free any Mdl we may have allocated. If the Mdl isn't - // present then we must have failed during the allocation - // phase. - // - - if (ThisIoRun->TransferMdl != IrpContext->Irp->MdlAddress) { - - if (ThisIoRun->TransferMdl != NULL) { - - IoFreeMdl( ThisIoRun->TransferMdl ); - } - - // - // Now free any buffer we may have allocated. If the Mdl - // doesn't match the original Mdl then free the buffer. - // - - if (ThisIoRun->TransferBuffer != NULL) { - - // - // If this is the final buffer for an XA read then store this buffer - // into the Vcb so that we will have it when reading any remaining - // portion of this buffer. - // - - if (SaveXABuffer) { - - Vcb = IrpContext->Vcb; - - CdLockVcb( IrpContext, Vcb ); - - if (Vcb->XASector != NULL) { - - CdFreePool( &Vcb->XASector ); - } - - Vcb->XASector = ThisIoRun->TransferBuffer; - Vcb->XADiskOffset = ThisIoRun->DiskOffset; - - SaveXABuffer = FALSE; - - CdUnlockVcb( IrpContext, Vcb ); - - // - // Otherwise just free the buffer. - // - - } else { - - CdFreePool( &ThisIoRun->TransferBuffer ); - } - } - } - } - - // - // Now handle the case where we failed in the process - // of allocating associated Irps and Mdls. - // - - if (ThisIoRun->SavedIrp != NULL) { - - if (ThisIoRun->SavedIrp->MdlAddress != NULL) { - - IoFreeMdl( ThisIoRun->SavedIrp->MdlAddress ); - } - - IoFreeIrp( ThisIoRun->SavedIrp ); - } - - // - // Move to the previous IoRun entry. - // - - ThisIoRun -= 1; - RemainingEntries -= 1; - } - - // - // If we copied any data then flush the Io buffers. - // - - return FlushIoBuffers; -} - - -// -// Local support routine -// - -VOID -CdMultipleAsync ( - IN PIRP_CONTEXT IrpContext, - IN ULONG RunCount, - IN PIO_RUN IoRuns - ) - -/*++ - -Routine Description: - - This routine first does the initial setup required of a Master IRP that is - going to be completed using associated IRPs. This routine should not - be used if only one async request is needed, instead the single read - async routines should be called. - - A context parameter is initialized, to serve as a communications area - between here and the common completion routine. - - Next this routine reads or writes one or more contiguous sectors from - a device asynchronously, and is used if there are multiple reads for a - master IRP. A completion routine is used to synchronize with the - completion of all of the I/O requests started by calls to this routine. - - Also, prior to calling this routine the caller must initialize the - IoStatus field in the Context, with the correct success status and byte - count which are expected if all of the parallel transfers complete - successfully. After return this status will be unchanged if all requests - were, in fact, successful. However, if one or more errors occur, the - IoStatus will be modified to reflect the error status and byte count - from the first run (by Vbo) which encountered an error. I/O status - from all subsequent runs will not be indicated. - -Arguments: - - RunCount - Supplies the number of multiple async requests - that will be issued against the master irp. - - IoRuns - Supplies an array containing the Offset and ByteCount for the - separate requests. - -Return Value: - - None. - ---*/ - -{ - PIO_COMPLETION_ROUTINE CompletionRoutine; - PIO_STACK_LOCATION IrpSp; - PMDL Mdl; - PIRP Irp; - PIRP MasterIrp; - ULONG UnwindRunCount; - - PAGED_CODE(); - - // - // Set up things according to whether this is truely async. - // - - CompletionRoutine = CdMultiSyncCompletionRoutine; - - if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - CompletionRoutine = CdMultiAsyncCompletionRoutine; - } - - // - // Initialize some local variables. - // - - MasterIrp = IrpContext->Irp; - - // - // Itterate through the runs, doing everything that can fail. - // We let the cleanup in CdFinishBuffers clean up on error. - // - - for (UnwindRunCount = 0; - UnwindRunCount < RunCount; - UnwindRunCount += 1) { - - // - // Create an associated IRP, making sure there is one stack entry for - // us, as well. - // - - IoRuns[UnwindRunCount].SavedIrp = - Irp = IoMakeAssociatedIrp( MasterIrp, (CCHAR)(IrpContext->Vcb->TargetDeviceObject->StackSize + 1) ); - - if (Irp == NULL) { - - IrpContext->Irp->IoStatus.Information = 0; - CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); - } - - // - // Allocate and build a partial Mdl for the request. - // - - Mdl = IoAllocateMdl( IoRuns[UnwindRunCount].TransferVirtualAddress, - IoRuns[UnwindRunCount].DiskByteCount, - FALSE, - FALSE, - Irp ); - - if (Mdl == NULL) { - - IrpContext->Irp->IoStatus.Information = 0; - CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); - } - - IoBuildPartialMdl( IoRuns[UnwindRunCount].TransferMdl, - Mdl, - IoRuns[UnwindRunCount].TransferVirtualAddress, - IoRuns[UnwindRunCount].DiskByteCount ); - - // - // Get the first IRP stack location in the associated Irp - // - - IoSetNextIrpStackLocation( Irp ); - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - // - // Setup the Stack location to describe our read. - // - - IrpSp->MajorFunction = IRP_MJ_READ; - IrpSp->Parameters.Read.Length = IoRuns[UnwindRunCount].DiskByteCount; - IrpSp->Parameters.Read.ByteOffset.QuadPart = IoRuns[UnwindRunCount].DiskOffset; - - // - // Set up the completion routine address in our stack frame. - // - - IoSetCompletionRoutine( Irp, - CompletionRoutine, - IrpContext->IoContext, - TRUE, - TRUE, - TRUE ); - - // - // Setup the next IRP stack location in the associated Irp for the disk - // driver beneath us. - // - - IrpSp = IoGetNextIrpStackLocation( Irp ); - - // - // Setup the Stack location to do a read from the disk driver. - // - - IrpSp->MajorFunction = IRP_MJ_READ; - IrpSp->Parameters.Read.Length = IoRuns[UnwindRunCount].DiskByteCount; - IrpSp->Parameters.Read.ByteOffset.QuadPart = IoRuns[UnwindRunCount].DiskOffset; - } - - // - // We only need to set the associated IRP count in the master irp to - // make it a master IRP. But we set the count to one more than our - // caller requested, because we do not want the I/O system to complete - // the I/O. We also set our own count. - // - - IrpContext->IoContext->IrpCount = RunCount; - IrpContext->IoContext->MasterIrp = MasterIrp; - - // - // We set the count in the master Irp to 1 since typically we - // will clean up the associated irps ourselves. Setting this to one - // means completing the last associated Irp with SUCCESS (in the async - // case) will complete the master irp. - // - - MasterIrp->AssociatedIrp.IrpCount = 1; - - // - // Now that all the dangerous work is done, issue the Io requests - // - - for (UnwindRunCount = 0; - UnwindRunCount < RunCount; - UnwindRunCount++) { - - Irp = IoRuns[UnwindRunCount].SavedIrp; - IoRuns[UnwindRunCount].SavedIrp = NULL; - - // - // If IoCallDriver returns an error, it has completed the Irp - // and the error will be caught by our completion routines - // and dealt with as a normal IO error. - // - - (VOID) IoCallDriver( IrpContext->Vcb->TargetDeviceObject, Irp ); - } - - return; -} - - -// -// Local support routine -// - -VOID -CdMultipleXAAsync ( - IN PIRP_CONTEXT IrpContext, - IN ULONG RunCount, - IN PIO_RUN IoRuns, - IN PRAW_READ_INFO RawReads, - IN TRACK_MODE_TYPE TrackMode - ) - -/*++ - -Routine Description: - - This routine first does the initial setup required of a Master IRP that is - going to be completed using associated IRPs. This routine is used to generate - the associated Irps used to read raw sectors from the disk. - - A context parameter is initialized, to serve as a communications area - between here and the common completion routine. - - Next this routine reads or writes one or more contiguous sectors from - a device asynchronously, and is used if there are multiple reads for a - master IRP. A completion routine is used to synchronize with the - completion of all of the I/O requests started by calls to this routine. - - Also, prior to calling this routine the caller must initialize the - IoStatus field in the Context, with the correct success status and byte - count which are expected if all of the parallel transfers complete - successfully. After return this status will be unchanged if all requests - were, in fact, successful. However, if one or more errors occur, the - IoStatus will be modified to reflect the error status and byte count - from the first run (by Vbo) which encountered an error. I/O status - from all subsequent runs will not be indicated. - -Arguments: - - RunCount - Supplies the number of multiple async requests - that will be issued against the master irp. - - IoRuns - Supplies an array containing the Offset and ByteCount for the - separate requests. - - RawReads - Supplies an array of structures to store in the Irps passed to the - device driver to perform the low-level Io. - - TrackMode - Supplies the recording mode of sectors in these IoRuns - -Return Value: - - None. - ---*/ - -{ - PIO_STACK_LOCATION IrpSp; - PMDL Mdl; - PIRP Irp; - PIRP MasterIrp; - ULONG UnwindRunCount; - ULONG RawByteCount; - - PIO_RUN ThisIoRun = IoRuns; - PRAW_READ_INFO ThisRawRead = RawReads; - - PAGED_CODE(); - - // - // Initialize some local variables. - // - - MasterIrp = IrpContext->Irp; - - // - // Itterate through the runs, doing everything that can fail. - // We let the cleanup in CdFinishBuffers clean up on error. - // - - for (UnwindRunCount = 0; - UnwindRunCount < RunCount; - UnwindRunCount += 1, ThisIoRun += 1, ThisRawRead += 1) { - - // - // Create an associated IRP, making sure there is one stack entry for - // us, as well. - // - - ThisIoRun->SavedIrp = - Irp = IoMakeAssociatedIrp( MasterIrp, (CCHAR)(IrpContext->Vcb->TargetDeviceObject->StackSize + 1) ); - - if (Irp == NULL) { - - IrpContext->Irp->IoStatus.Information = 0; - CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); - } - - // - // Should have been passed a byte count of at least one sector, and - // must be a multiple of sector size - // - - ASSERT( ThisIoRun->DiskByteCount && !SectorOffset(ThisIoRun->DiskByteCount)); - - RawByteCount = SectorsFromBytes( ThisIoRun->DiskByteCount) * RAW_SECTOR_SIZE; - - // - // Allocate and build a partial Mdl for the request. - // - - Mdl = IoAllocateMdl( ThisIoRun->TransferVirtualAddress, - RawByteCount, - FALSE, - FALSE, - Irp ); - - if (Mdl == NULL) { - - IrpContext->Irp->IoStatus.Information = 0; - CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); - } - - IoBuildPartialMdl( ThisIoRun->TransferMdl, - Mdl, - ThisIoRun->TransferVirtualAddress, - RawByteCount); - // - // Get the first IRP stack location in the associated Irp - // - - IoSetNextIrpStackLocation( Irp ); - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - // - // Setup the Stack location to describe our read (using cooked values) - // These values won't be used for the raw read in any case. - // - - IrpSp->MajorFunction = IRP_MJ_READ; - IrpSp->Parameters.Read.Length = ThisIoRun->DiskByteCount; - IrpSp->Parameters.Read.ByteOffset.QuadPart = ThisIoRun->DiskOffset; - - // - // Set up the completion routine address in our stack frame. - // - - IoSetCompletionRoutine( Irp, - CdMultiSyncCompletionRoutine, - IrpContext->IoContext, - TRUE, - TRUE, - TRUE ); - - // - // Setup the next IRP stack location in the associated Irp for the disk - // driver beneath us. - // - - IrpSp = IoGetNextIrpStackLocation( Irp ); - - // - // Setup the stack location to do a read of raw sectors at this location. - // Note that the storage stack always reads multiples of whole XA sectors. - // - - ThisRawRead->DiskOffset.QuadPart = ThisIoRun->DiskOffset; - ThisRawRead->SectorCount = ThisIoRun->DiskByteCount >> SECTOR_SHIFT; - ThisRawRead->TrackMode = TrackMode; - - IrpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL; - - IrpSp->Parameters.DeviceIoControl.OutputBufferLength = ThisRawRead->SectorCount * RAW_SECTOR_SIZE; - Irp->UserBuffer = ThisIoRun->TransferVirtualAddress; - - IrpSp->Parameters.DeviceIoControl.InputBufferLength = sizeof( RAW_READ_INFO ); - IrpSp->Parameters.DeviceIoControl.Type3InputBuffer = ThisRawRead; - - IrpSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_CDROM_RAW_READ; - } - - // - // We only need to set the associated IRP count in the master irp to - // make it a master IRP. But we set the count to one more than our - // caller requested, because we do not want the I/O system to complete - // the I/O. We also set our own count. - // - - IrpContext->IoContext->IrpCount = RunCount; - IrpContext->IoContext->MasterIrp = MasterIrp; - - // - // We set the count in the master Irp to 1 since typically we - // will clean up the associated irps ourselves. Setting this to one - // means completing the last associated Irp with SUCCESS (in the async - // case) will complete the master irp. - // - - MasterIrp->AssociatedIrp.IrpCount = 1; - - // - // Now that all the dangerous work is done, issue the Io requests - // - - for (UnwindRunCount = 0; - UnwindRunCount < RunCount; - UnwindRunCount++) { - - Irp = IoRuns[UnwindRunCount].SavedIrp; - IoRuns[UnwindRunCount].SavedIrp = NULL; - - // - // - // If IoCallDriver returns an error, it has completed the Irp - // and the error will be caught by our completion routines - // and dealt with as a normal IO error. - // - - (VOID) IoCallDriver( IrpContext->Vcb->TargetDeviceObject, Irp ); - } - - return; -} - - -// -// Local support routine -// - -VOID -CdSingleAsync ( - IN PIRP_CONTEXT IrpContext, - IN LONGLONG ByteOffset, - IN ULONG ByteCount - ) - -/*++ - -Routine Description: - - This routine reads one or more contiguous sectors from a device - asynchronously, and is used if there is only one read necessary to - complete the IRP. It implements the read by simply filling - in the next stack frame in the Irp, and passing it on. The transfer - occurs to the single buffer originally specified in the user request. - -Arguments: - - ByteOffset - Supplies the starting Logical Byte Offset to begin reading from - - ByteCount - Supplies the number of bytes to read from the device - -Return Value: - - None. - ---*/ - -{ - PIO_STACK_LOCATION IrpSp; - PIO_COMPLETION_ROUTINE CompletionRoutine; - - PAGED_CODE(); - - // - // Set up things according to whether this is truely async. - // - - if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - CompletionRoutine = CdSingleSyncCompletionRoutine; - - } else { - - CompletionRoutine = CdSingleAsyncCompletionRoutine; - } - - // - // Set up the completion routine address in our stack frame. - // - - IoSetCompletionRoutine( IrpContext->Irp, - CompletionRoutine, - IrpContext->IoContext, - TRUE, - TRUE, - TRUE ); - - // - // Setup the next IRP stack location in the associated Irp for the disk - // driver beneath us. - // - - IrpSp = IoGetNextIrpStackLocation( IrpContext->Irp ); - - // - // Setup the Stack location to do a read from the disk driver. - // - - IrpSp->MajorFunction = IRP_MJ_READ; - IrpSp->Parameters.Read.Length = ByteCount; - IrpSp->Parameters.Read.ByteOffset.QuadPart = ByteOffset; - - // - // Issue the Io request - // - - // - // If IoCallDriver returns an error, it has completed the Irp - // and the error will be caught by our completion routines - // and dealt with as a normal IO error. - // - - (VOID)IoCallDriver( IrpContext->Vcb->TargetDeviceObject, IrpContext->Irp ); - - // - // And return to our caller - // - - return; -} - - -// -// Local support routine -// - -VOID -CdWaitSync ( - IN PIRP_CONTEXT IrpContext - ) - -/*++ - -Routine Description: - - This routine waits for one or more previously started I/O requests - from the above routines, by simply waiting on the event. - -Arguments: - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - KeWaitForSingleObject( &IrpContext->IoContext->SyncEvent, - Executive, - KernelMode, - FALSE, - NULL ); - - KeClearEvent( &IrpContext->IoContext->SyncEvent ); - - return; -} - - -// -// Local support routine -// - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdMultiSyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ) - -/*++ - -Routine Description: - - This is the completion routine for all synchronous reads - started via CdMultipleAsynch. - - The completion routine has has the following responsibilities: - - If the individual request was completed with an error, then - this completion routine must see if this is the first error - and remember the error status in the Context. - - If the IrpCount goes to 1, then it sets the event in the Context - parameter to signal the caller that all of the asynch requests - are done. - -Arguments: - - DeviceObject - Pointer to the file system device object. - - Irp - Pointer to the associated Irp which is being completed. (This - Irp will no longer be accessible after this routine returns.) - - Context - The context parameter which was specified for all of - the multiple asynch I/O requests for this MasterIrp. - -Return Value: - - The routine returns STATUS_MORE_PROCESSING_REQUIRED so that we can - immediately complete the Master Irp without being in a race condition - with the IoCompleteRequest thread trying to decrement the IrpCount in - the Master Irp. - ---*/ - -{ - PCD_IO_CONTEXT IoContext = Context; - - AssertVerifyDeviceIrp( Irp ); - - // - // If we got an error (or verify required), remember it in the Irp - // - - if (!NT_SUCCESS( Irp->IoStatus.Status )) { - - InterlockedExchange( &IoContext->Status, Irp->IoStatus.Status ); - IoContext->MasterIrp->IoStatus.Information = 0; - } - - // - // We must do this here since IoCompleteRequest won't get a chance - // on this associated Irp. - // - - IoFreeMdl( Irp->MdlAddress ); - IoFreeIrp( Irp ); - - if (InterlockedDecrement( &IoContext->IrpCount ) == 0) { - - // - // Update the Master Irp with any error status from the associated Irps. - // - - IoContext->MasterIrp->IoStatus.Status = IoContext->Status; - KeSetEvent( &IoContext->SyncEvent, 0, FALSE ); - } - - UNREFERENCED_PARAMETER( DeviceObject ); - - return STATUS_MORE_PROCESSING_REQUIRED; -} - - -// -// Local support routine -// - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdMultiAsyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ) - -/*++ - -Routine Description: - - This is the completion routine for all asynchronous reads - started via CdMultipleAsynch. - - The completion routine has has the following responsibilities: - - If the individual request was completed with an error, then - this completion routine must see if this is the first error - and remember the error status in the Context. - -Arguments: - - DeviceObject - Pointer to the file system device object. - - Irp - Pointer to the associated Irp which is being completed. (This - Irp will no longer be accessible after this routine returns.) - - Context - The context parameter which was specified for all of - the multiple asynch I/O requests for this MasterIrp. - -Return Value: - - Currently always returns STATUS_SUCCESS. - ---*/ - -{ - PCD_IO_CONTEXT IoContext = Context; - /* ReactOS Change: GCC Unused Variable */ - //PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - AssertVerifyDeviceIrp( Irp ); - - // - // If we got an error (or verify required), remember it in the Irp - // - - if (!NT_SUCCESS( Irp->IoStatus.Status )) { - - InterlockedExchange( &IoContext->Status, Irp->IoStatus.Status ); - } - - // - // Decrement IrpCount and see if it goes to zero. - // - - if (InterlockedDecrement( &IoContext->IrpCount ) == 0) { - - // - // Mark the master Irp pending - // - - IoMarkIrpPending( IoContext->MasterIrp ); - - // - // Update the Master Irp with any error status from the associated Irps. - // - - IoContext->MasterIrp->IoStatus.Status = IoContext->Status; - - // - // Update the information field with the correct value. - // - - IoContext->MasterIrp->IoStatus.Information = 0; - - if (NT_SUCCESS( IoContext->MasterIrp->IoStatus.Status )) { - - IoContext->MasterIrp->IoStatus.Information = IoContext->RequestedByteCount; - } - - // - // Now release the resource - // - - ExReleaseResourceForThreadLite( IoContext->Resource, - IoContext->ResourceThreadId ); - - // - // and finally, free the context record. - // - - CdFreeIoContext( IoContext ); - - // - // Return success in this case. - // - - return STATUS_SUCCESS; - - } else { - - // - // We need to cleanup the associated Irp and its Mdl. - // - - IoFreeMdl( Irp->MdlAddress ); - IoFreeIrp( Irp ); - - return STATUS_MORE_PROCESSING_REQUIRED; - } - - UNREFERENCED_PARAMETER( DeviceObject ); -} - - -// -// Local support routine -// - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdSingleSyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ) - -/*++ - -Routine Description: - - This is the completion routine for all reads started via CdSingleAsynch. - - The completion routine has has the following responsibilities: - - It sets the event in the Context parameter to signal the caller - that all of the asynch requests are done. - -Arguments: - - DeviceObject - Pointer to the file system device object. - - Irp - Pointer to the Irp for this request. (This Irp will no longer - be accessible after this routine returns.) - - Context - The context parameter which was specified in the call to - CdSingleAsynch. - -Return Value: - - The routine returns STATUS_MORE_PROCESSING_REQUIRED so that we can - immediately complete the Master Irp without being in a race condition - with the IoCompleteRequest thread trying to decrement the IrpCount in - the Master Irp. - ---*/ - -{ - AssertVerifyDeviceIrp( Irp ); - - // - // Store the correct information field into the Irp. - // - - if (!NT_SUCCESS( Irp->IoStatus.Status )) { - - Irp->IoStatus.Information = 0; - } - - KeSetEvent( &((PCD_IO_CONTEXT)Context)->SyncEvent, 0, FALSE ); - - return STATUS_MORE_PROCESSING_REQUIRED; -} - - -// -// Local support routine -// - -NTSTATUS -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdSingleAsyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ) - -/*++ - -Routine Description: - - This is the completion routine for all asynchronous reads - started via CdSingleAsynch. - -Arguments: - - DeviceObject - Pointer to the file system device object. - - Irp - Pointer to the Irp for this request. (This Irp will no longer - be accessible after this routine returns.) - - Context - The context parameter which was specified in the call to - CdSingleAsynch. - -Return Value: - - Currently always returns STATUS_SUCCESS. - ---*/ - -{ - AssertVerifyDeviceIrp( Irp ); - - // - // Update the information field with the correct value for bytes read. - // - - Irp->IoStatus.Information = 0; - - if (NT_SUCCESS( Irp->IoStatus.Status )) { - - Irp->IoStatus.Information = ((PCD_IO_CONTEXT) Context)->RequestedByteCount; - } - - // - // Mark the Irp pending - // - - IoMarkIrpPending( Irp ); - - // - // Now release the resource - // - - ExReleaseResourceForThreadLite( ((PCD_IO_CONTEXT) Context)->Resource, - ((PCD_IO_CONTEXT) Context)->ResourceThreadId ); - - // - // and finally, free the context record. - // - - CdFreeIoContext( Context ); /* ReactOS Change: GCC "error: invalid lvalue in unary '&'" */ - return STATUS_SUCCESS; - - UNREFERENCED_PARAMETER( DeviceObject ); -} - - -// -// Local support routine -// - -VOID -CdReadAudioSystemFile ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG StartingOffset, - IN ULONG ByteCount, - IN PVOID SystemBuffer - ) - -/*++ - -Routine Description: - - This routine is called to read the pseudo root directory and path - table for a music disk. We build the individual elements on the - stack and copy into the cache buffer. - -Arguments: - - Fcb - Fcb representing the file to read. - - StartingOffset - Logical offset in the file to read from. - - ByteCount - Number of bytes to read. - - SystemBuffer - Pointer to buffer to fill in. This will always be page - aligned. - -Return Value: - - None. - ---*/ - -{ - PRAW_PATH_ISO RawPath; - PRAW_DIRENT RawDirent; - - ULONG CurrentTrack; - ULONG SectorOffset; - ULONG EntryCount; - UCHAR TrackOnes; - UCHAR TrackTens; - PTRACK_DATA ThisTrack; - - LONGLONG CurrentOffset; - - PVOID CurrentSector; - - PSYSTEM_USE_XA SystemUse; - - ULONG BytesToCopy; - - UCHAR LocalBuffer[FIELD_OFFSET( RAW_DIRENT, FileId ) + 12]; - - PAGED_CODE(); - - // - // If this is the path table then we just need a single entry. - // - - if (SafeNodeType( Fcb ) == CDFS_NTC_FCB_PATH_TABLE) { - - // - // Sanity check that the offset is zero. - // - - ASSERT( StartingOffset == 0 ); - - // - // Store a pseudo path entry in our local buffer. - // - - RawPath = (PRAW_PATH_ISO) LocalBuffer; - - RtlZeroMemory( RawPath, sizeof( LocalBuffer )); - - RawPath->DirIdLen = 1; - RawPath->ParentNum = 1; - RawPath->DirId[0] = '\0'; - - // - // Now copy to the user's buffer. - // - - BytesToCopy = FIELD_OFFSET( RAW_PATH_ISO, DirId ) + 2; - - if (BytesToCopy > ByteCount) { - - BytesToCopy = ByteCount; - } - - RtlCopyMemory( SystemBuffer, - RawPath, - BytesToCopy ); - - // - // We need to deal with the multiple sector case for the root directory. - // - - } else { - - // - // Initialize the first track to return to our caller. - // - - CurrentTrack = 0; - - // - // If the offset is zero then store the entries for the self and parent - // entries. - // - - if (StartingOffset == 0) { - - RawDirent = SystemBuffer; - - // - // Clear all of the fields initially. - // - - RtlZeroMemory( RawDirent, FIELD_OFFSET( RAW_DIRENT, FileId )); - - // - // Now fill in the interesting fields. - // - - RawDirent->DirLen = FIELD_OFFSET( RAW_DIRENT, FileId ) + 1; - RawDirent->FileIdLen = 1; - RawDirent->FileId[0] = '\0'; - SetFlag( RawDirent->FlagsISO, CD_ATTRIBUTE_DIRECTORY ); - - // - // Set the time stamp to be Jan 1, 1995 - // - - RawDirent->RecordTime[0] = 95; - RawDirent->RecordTime[1] = 1; - RawDirent->RecordTime[2] = 1; - - SectorOffset = RawDirent->DirLen; - - RawDirent = Add2Ptr( RawDirent, SectorOffset, PRAW_DIRENT ); - - // - // Clear all of the fields initially. - // - - RtlZeroMemory( RawDirent, FIELD_OFFSET( RAW_DIRENT, FileId )); - - // - // Now fill in the interesting fields. - // - - RawDirent->DirLen = FIELD_OFFSET( RAW_DIRENT, FileId ) + 1; - RawDirent->FileIdLen = 1; - RawDirent->FileId[0] = '\1'; - SetFlag( RawDirent->FlagsISO, CD_ATTRIBUTE_DIRECTORY ); - - // - // Set the time stamp to be Jan 1, 1995 - // - - RawDirent->RecordTime[0] = 95; - RawDirent->RecordTime[1] = 1; - RawDirent->RecordTime[2] = 1; - - SectorOffset += RawDirent->DirLen; - EntryCount = 2; - - // - // Otherwise compute the starting track to write to the buffer. - // - - } else { - - // - // Count the tracks in each preceding sector. - // - - CurrentOffset = 0; - - do { - - CurrentTrack += CdAudioDirentsPerSector; - CurrentOffset += SECTOR_SIZE; - - } while (CurrentOffset < StartingOffset); - - // - // Bias the track count to reflect the two default entries. - // - - CurrentTrack -= 2; - - SectorOffset = 0; - EntryCount = 0; - } - - // - // We now know the first track to return as well as where we are in - // the current sector. We will walk through sector by sector adding - // the entries for the separate tracks in the TOC. We will zero - // any sectors or partial sectors without data. - // - - CurrentSector = SystemBuffer; - BytesToCopy = SECTOR_SIZE; - - // - // Loop for each sector. - // - - do { - - // - // Add entries until we reach our threshold for each sector. - // - - do { - - // - // If we are beyond the entries in the TOC then exit. - // - - if (CurrentTrack >= IrpContext->Vcb->TrackCount) { - - break; - } - - ThisTrack = &IrpContext->Vcb->CdromToc->TrackData[CurrentTrack]; - - // - // Point to the current position in the buffer. - // - - RawDirent = Add2Ptr( CurrentSector, SectorOffset, PRAW_DIRENT ); - - // - // Clear all of the fields initially. - // - - RtlZeroMemory( RawDirent, CdAudioDirentSize ); - - // - // Now fill in the interesting fields. - // - - RawDirent->DirLen = (UCHAR) CdAudioDirentSize; - RawDirent->FileIdLen = CdAudioFileNameLength; - - RtlCopyMemory( RawDirent->FileId, - CdAudioFileName, - CdAudioFileNameLength ); - - // - // Set the time stamp to be Jan 1, 1995 - // - - RawDirent->RecordTime[0] = 95; - RawDirent->RecordTime[1] = 1; - RawDirent->RecordTime[2] = 1; - - // - // Now bias by the values in the TOC. - // - - RawDirent->RecordTime[4] = ThisTrack->Address[1] % 60; - RawDirent->RecordTime[5] = ThisTrack->Address[2] % 60; - - // - // Put the track number into the file name. - // - - TrackTens = TrackOnes = ThisTrack->TrackNumber; - - TrackOnes = (TrackOnes % 10) + '0'; - - TrackTens /= 10; - TrackTens = (TrackTens % 10) + '0'; - - RawDirent->FileId[AUDIO_NAME_TENS_OFFSET] = TrackTens; - RawDirent->FileId[AUDIO_NAME_ONES_OFFSET] = TrackOnes; - - SystemUse = Add2Ptr( RawDirent, CdAudioSystemUseOffset, PSYSTEM_USE_XA ); - - SystemUse->Attributes = SYSTEM_USE_XA_DA; - SystemUse->Signature = SYSTEM_XA_SIGNATURE; - - // - // Store the track number as the file number. - // - - SystemUse->FileNumber = (UCHAR) CurrentTrack; - - EntryCount += 1; - SectorOffset += CdAudioDirentSize; - CurrentTrack += 1; - - } while (EntryCount < CdAudioDirentsPerSector); - - // - // Zero the remaining portion of this buffer. - // - - RtlZeroMemory( Add2Ptr( CurrentSector, SectorOffset, PVOID ), - SECTOR_SIZE - SectorOffset ); - - // - // Prepare for the next sector. - // - - EntryCount = 0; - BytesToCopy += SECTOR_SIZE; - SectorOffset = 0; - CurrentSector = Add2Ptr( CurrentSector, SECTOR_SIZE, PVOID ); - - } while (BytesToCopy <= ByteCount); - } - - return; -} - diff --git a/reactos/drivers/filesystems/cdfs_new/dirctrl.c b/reactos/drivers/filesystems/cdfs_new/dirctrl.c deleted file mode 100755 index 53e9e31a7b4..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/dirctrl.c +++ /dev/null @@ -1,1523 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - DirCtrl.c - -Abstract: - - This module implements the File Directory Control routines for Cdfs called - by the Fsd/Fsp dispatch drivers. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_DIRCTRL) - -// -// Local support routines -// - -NTSTATUS -CdQueryDirectory ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PIO_STACK_LOCATION IrpSp, - IN PFCB Fcb, - IN PCCB Ccb - ); - -NTSTATUS -CdNotifyChangeDirectory ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PIO_STACK_LOCATION IrpSp, - IN PCCB Ccb - ); - -VOID -CdInitializeEnumeration ( - IN PIRP_CONTEXT IrpContext, - IN PIO_STACK_LOCATION IrpSp, - IN PFCB Fcb, - IN OUT PCCB Ccb, - IN OUT PFILE_ENUM_CONTEXT FileContext, - OUT PBOOLEAN ReturnNextEntry, - OUT PBOOLEAN ReturnSingleEntry, - OUT PBOOLEAN InitialQuery - ); - -BOOLEAN -CdEnumerateIndex ( - IN PIRP_CONTEXT IrpContext, - IN PCCB Ccb, - IN OUT PFILE_ENUM_CONTEXT FileContext, - IN BOOLEAN ReturnNextEntry - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCommonDirControl) -#pragma alloc_text(PAGE, CdEnumerateIndex) -#pragma alloc_text(PAGE, CdInitializeEnumeration) -#pragma alloc_text(PAGE, CdNotifyChangeDirectory) -#pragma alloc_text(PAGE, CdQueryDirectory) -#endif - - -NTSTATUS -CdCommonDirControl ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine is the entry point for the directory control operations. These - are directory enumerations and directory notify calls. We verify the - user's handle is for a directory and then call the appropriate routine. - -Arguments: - - Irp - Irp for this request. - -Return Value: - - NTSTATUS - Status returned from the lower level routines. - ---*/ - -{ - NTSTATUS Status; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PFCB Fcb; - PCCB Ccb; - - PAGED_CODE(); - - // - // Decode the user file object and fail this request if it is not - // a user directory. - // - - if (CdDecodeFileObject( IrpContext, - IrpSp->FileObject, - &Fcb, - &Ccb ) != UserDirectoryOpen) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - // - // We know this is a directory control so we'll case on the - // minor function, and call a internal worker routine to complete - // the irp. - // - - switch (IrpSp->MinorFunction) { - - case IRP_MN_QUERY_DIRECTORY: - - Status = CdQueryDirectory( IrpContext, Irp, IrpSp, Fcb, Ccb ); - break; - - case IRP_MN_NOTIFY_CHANGE_DIRECTORY: - - Status = CdNotifyChangeDirectory( IrpContext, Irp, IrpSp, Ccb ); - break; - - default: - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST ); - Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - - return Status; -} - - -// -// Local support routines -// - -NTSTATUS -CdQueryDirectory ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PIO_STACK_LOCATION IrpSp, - IN PFCB Fcb, - IN PCCB Ccb - ) - -/*++ - -Routine Description: - - This routine performs the query directory operation. It is responsible - for either completing of enqueuing the input Irp. We store the state of the - search in the Ccb. - -Arguments: - - Irp - Supplies the Irp to process - - IrpSp - Stack location for this Irp. - - Fcb - Fcb for this directory. - - Ccb - Ccb for this directory open. - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status = STATUS_SUCCESS; - ULONG Information = 0; - - ULONG LastEntry = 0; - ULONG NextEntry = 0; - - ULONG FileNameBytes; - ULONG SeparatorBytes; - ULONG VersionStringBytes; - - FILE_ENUM_CONTEXT FileContext; - PDIRENT ThisDirent; - BOOLEAN InitialQuery; - BOOLEAN ReturnNextEntry; - BOOLEAN ReturnSingleEntry; - BOOLEAN Found; - BOOLEAN DoCcbUpdate = FALSE; - - PCHAR UserBuffer; - ULONG BytesRemainingInBuffer; - - ULONG BaseLength; - - PFILE_BOTH_DIR_INFORMATION DirInfo = NULL; /* ReactOS Change: GCC Uninit var */ - PFILE_NAMES_INFORMATION NamesInfo; - PFILE_ID_FULL_DIR_INFORMATION IdFullDirInfo; - PFILE_ID_BOTH_DIR_INFORMATION IdBothDirInfo; - - PAGED_CODE(); - - // - // Check if we support this search mode. Also remember the size of the base part of - // each of these structures. - // - - switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) { - - case FileDirectoryInformation: - - BaseLength = FIELD_OFFSET( FILE_DIRECTORY_INFORMATION, - FileName[0] ); - break; - - case FileFullDirectoryInformation: - - BaseLength = FIELD_OFFSET( FILE_FULL_DIR_INFORMATION, - FileName[0] ); - break; - - case FileIdFullDirectoryInformation: - - BaseLength = FIELD_OFFSET( FILE_ID_FULL_DIR_INFORMATION, - FileName[0] ); - break; - - case FileNamesInformation: - - BaseLength = FIELD_OFFSET( FILE_NAMES_INFORMATION, - FileName[0] ); - break; - - case FileBothDirectoryInformation: - - BaseLength = FIELD_OFFSET( FILE_BOTH_DIR_INFORMATION, - FileName[0] ); - break; - - case FileIdBothDirectoryInformation: - - BaseLength = FIELD_OFFSET( FILE_ID_BOTH_DIR_INFORMATION, - FileName[0] ); - break; - - default: - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_INFO_CLASS ); - return STATUS_INVALID_INFO_CLASS; - } - - // - // Get the user buffer. - // - - CdMapUserBuffer( IrpContext, &UserBuffer); - - // - // Initialize our search context. - // - - CdInitializeFileContext( IrpContext, &FileContext ); - - // - // Acquire the directory. - // - - CdAcquireFileShared( IrpContext, Fcb ); - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Verify the Fcb is still good. - // - - CdVerifyFcbOperation( IrpContext, Fcb ); - - // - // Start by getting the initial state for the enumeration. This will set up the Ccb with - // the initial search parameters and let us know the starting offset in the directory - // to search. - // - - CdInitializeEnumeration( IrpContext, - IrpSp, - Fcb, - Ccb, - &FileContext, - &ReturnNextEntry, - &ReturnSingleEntry, - &InitialQuery ); - - // - // The current dirent is stored in the InitialDirent field. We capture - // this here so that we have a valid restart point even if we don't - // find a single entry. - // - - ThisDirent = &FileContext.InitialDirent->Dirent; - - // - // At this point we are about to enter our query loop. We have - // determined the index into the directory file to begin the - // search. LastEntry and NextEntry are used to index into the user - // buffer. LastEntry is the last entry we've added, NextEntry is - // current one we're working on. If NextEntry is non-zero, then - // at least one entry was added. - // - - while (TRUE) { - - // - // If the user had requested only a single match and we have - // returned that, then we stop at this point. We update the Ccb with - // the status based on the last entry returned. - // - - if ((NextEntry != 0) && ReturnSingleEntry) { - - DoCcbUpdate = TRUE; - try_leave( Status ); - } - - // - // We try to locate the next matching dirent. Our search if based on a starting - // dirent offset, whether we should return the current or next entry, whether - // we should be doing a short name search and finally whether we should be - // checking for a version match. - // - - Found = CdEnumerateIndex( IrpContext, Ccb, &FileContext, ReturnNextEntry ); - - // - // Initialize the value for the next search. - // - - ReturnNextEntry = TRUE; - - // - // If we didn't receive a dirent, then we are at the end of the - // directory. If we have returned any files, we exit with - // success, otherwise we return STATUS_NO_MORE_FILES. - // - - if (!Found) { - - if (NextEntry == 0) { - - Status = STATUS_NO_MORE_FILES; - - if (InitialQuery) { - - Status = STATUS_NO_SUCH_FILE; - } - } - - DoCcbUpdate = TRUE; - try_leave( Status ); - } - - // - // Remember the dirent for the file we just found. - // - - ThisDirent = &FileContext.InitialDirent->Dirent; - - // - // Here are the rules concerning filling up the buffer: - // - // 1. The Io system garentees that there will always be - // enough room for at least one base record. - // - // 2. If the full first record (including file name) cannot - // fit, as much of the name as possible is copied and - // STATUS_BUFFER_OVERFLOW is returned. - // - // 3. If a subsequent record cannot completely fit into the - // buffer, none of it (as in 0 bytes) is copied, and - // STATUS_SUCCESS is returned. A subsequent query will - // pick up with this record. - // - - // - // Let's compute the number of bytes we need to transfer the current entry. - // - - SeparatorBytes = - VersionStringBytes = 0; - - // - // We can look directly at the dirent that we found. - // - - FileNameBytes = ThisDirent->CdFileName.FileName.Length; - - // - // Compute the number of bytes for the version string if - // we will return this. Allow directories with illegal ";". - // - - if (((Ccb->SearchExpression.VersionString.Length != 0) || - (FlagOn(ThisDirent->DirentFlags, CD_ATTRIBUTE_DIRECTORY))) && - (ThisDirent->CdFileName.VersionString.Length != 0)) { - - SeparatorBytes = 2; - - VersionStringBytes = ThisDirent->CdFileName.VersionString.Length; - } - - // - // If the slot for the next entry would be beyond the length of the - // user's buffer just exit (we know we've returned at least one entry - // already). This will happen when we align the pointer past the end. - // - - if (NextEntry > IrpSp->Parameters.QueryDirectory.Length) { - - ReturnNextEntry = FALSE; - DoCcbUpdate = TRUE; - try_leave( Status = STATUS_SUCCESS ); - } - - // - // Compute the number of bytes remaining in the buffer. Round this - // down to a WCHAR boundary so we can copy full characters. - // - - BytesRemainingInBuffer = IrpSp->Parameters.QueryDirectory.Length - NextEntry; - ClearFlag( BytesRemainingInBuffer, 1 ); - - // - // If this won't fit and we have returned a previous entry then just - // return STATUS_SUCCESS. - // - - if ((BaseLength + FileNameBytes + SeparatorBytes + VersionStringBytes) > BytesRemainingInBuffer) { - - // - // If we already found an entry then just exit. - // - - if (NextEntry != 0) { - - ReturnNextEntry = FALSE; - DoCcbUpdate = TRUE; - try_leave( Status = STATUS_SUCCESS ); - } - - // - // Don't even try to return the version string if it doesn't all fit. - // Reduce the FileNameBytes to just fit in the buffer. - // - - if ((BaseLength + FileNameBytes) > BytesRemainingInBuffer) { - - FileNameBytes = BytesRemainingInBuffer - BaseLength; - } - - // - // Don't return any version string bytes. - // - - VersionStringBytes = - SeparatorBytes = 0; - - // - // Use a status code of STATUS_BUFFER_OVERFLOW. Also set - // ReturnSingleEntry so that we will exit the loop at the top. - // - - Status = STATUS_BUFFER_OVERFLOW; - ReturnSingleEntry = TRUE; - } - - // - // Protect access to the user buffer with an exception handler. - // Since (at our request) IO doesn't buffer these requests, we have - // to guard against a user messing with the page protection and other - // such trickery. - // - - try { - - // - // Zero and initialize the base part of the current entry. - // - - RtlZeroMemory( Add2Ptr( UserBuffer, NextEntry, PVOID ), - BaseLength ); - - // - // Now we have an entry to return to our caller. - // We'll case on the type of information requested and fill up - // the user buffer if everything fits. - // - - switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) { - - case FileBothDirectoryInformation: - case FileFullDirectoryInformation: - case FileIdBothDirectoryInformation: - case FileIdFullDirectoryInformation: - case FileDirectoryInformation: - - DirInfo = Add2Ptr( UserBuffer, NextEntry, PFILE_BOTH_DIR_INFORMATION ); - - // - // Use the create time for all the time stamps. - // - - CdConvertCdTimeToNtTime( IrpContext, - FileContext.InitialDirent->Dirent.CdTime, - &DirInfo->CreationTime ); - - DirInfo->LastWriteTime = DirInfo->ChangeTime = DirInfo->CreationTime; - - // - // Set the attributes and sizes separately for directories and - // files. - // - - if (FlagOn( ThisDirent->DirentFlags, CD_ATTRIBUTE_DIRECTORY )) { - - DirInfo->EndOfFile.QuadPart = DirInfo->AllocationSize.QuadPart = 0; - - SetFlag( DirInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY ); - - } else { - - DirInfo->EndOfFile.QuadPart = FileContext.FileSize; - DirInfo->AllocationSize.QuadPart = LlSectorAlign( FileContext.FileSize ); - } - - // - // All Cdrom files are readonly. We also copy the existence - // bit to the hidden attribute. - // - - SetFlag( DirInfo->FileAttributes, FILE_ATTRIBUTE_READONLY ); - - if (FlagOn( ThisDirent->DirentFlags, - CD_ATTRIBUTE_HIDDEN )) { - - SetFlag( DirInfo->FileAttributes, FILE_ATTRIBUTE_HIDDEN ); - } - - DirInfo->FileIndex = ThisDirent->DirentOffset; - - DirInfo->FileNameLength = FileNameBytes + SeparatorBytes + VersionStringBytes; - - break; - - case FileNamesInformation: - - NamesInfo = Add2Ptr( UserBuffer, NextEntry, PFILE_NAMES_INFORMATION ); - - NamesInfo->FileIndex = ThisDirent->DirentOffset; - - NamesInfo->FileNameLength = FileNameBytes + SeparatorBytes + VersionStringBytes; - - break; - - /* ReactOS Change: GCC "enumeration value not handled in switch" */ - default: break; - } - - // - // Fill in the FileId - // - - switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) { - - case FileIdBothDirectoryInformation: - - IdBothDirInfo = Add2Ptr( UserBuffer, NextEntry, PFILE_ID_BOTH_DIR_INFORMATION ); - CdSetFidFromParentAndDirent( IdBothDirInfo->FileId, Fcb, ThisDirent ); - break; - - case FileIdFullDirectoryInformation: - - IdFullDirInfo = Add2Ptr( UserBuffer, NextEntry, PFILE_ID_FULL_DIR_INFORMATION ); - CdSetFidFromParentAndDirent( IdFullDirInfo->FileId, Fcb, ThisDirent ); - break; - - default: - break; - } - - // - // Now copy as much of the name as possible. We also may have a version - // string to copy. - // - - if (FileNameBytes != 0) { - - // - // This is a Unicode name, we can copy the bytes directly. - // - - RtlCopyMemory( Add2Ptr( UserBuffer, NextEntry + BaseLength, PVOID ), - ThisDirent->CdFileName.FileName.Buffer, - FileNameBytes ); - - if (SeparatorBytes != 0) { - - *(Add2Ptr( UserBuffer, - NextEntry + BaseLength + FileNameBytes, - PWCHAR )) = L';'; - - if (VersionStringBytes != 0) { - - RtlCopyMemory( Add2Ptr( UserBuffer, - NextEntry + BaseLength + FileNameBytes + sizeof( WCHAR ), - PVOID ), - ThisDirent->CdFileName.VersionString.Buffer, - VersionStringBytes ); - } - } - } - - // - // Fill in the short name if we got STATUS_SUCCESS. The short name - // may already be in the file context. Otherwise we will check - // whether the long name is 8.3. Special case the self and parent - // directory names. - // - - if ((Status == STATUS_SUCCESS) && - (IrpSp->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation || - IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdBothDirectoryInformation) && - (Ccb->SearchExpression.VersionString.Length == 0) && - !FlagOn( ThisDirent->Flags, DIRENT_FLAG_CONSTANT_ENTRY )) { - - // - // If we already have the short name then copy into the user's buffer. - // - - if (FileContext.ShortName.FileName.Length != 0) { - - RtlCopyMemory( DirInfo->ShortName, - FileContext.ShortName.FileName.Buffer, - FileContext.ShortName.FileName.Length ); - - DirInfo->ShortNameLength = (CCHAR) FileContext.ShortName.FileName.Length; - - // - // If the short name length is currently zero then check if - // the long name is not 8.3. We can copy the short name in - // unicode form directly into the caller's buffer. - // - - } else { - - if (!CdIs8dot3Name( IrpContext, - ThisDirent->CdFileName.FileName )) { - - CdGenerate8dot3Name( IrpContext, - &ThisDirent->CdCaseFileName.FileName, - ThisDirent->DirentOffset, - DirInfo->ShortName, - &FileContext.ShortName.FileName.Length ); - - DirInfo->ShortNameLength = (CCHAR) FileContext.ShortName.FileName.Length; - } - } - - } - - // - // Sum the total number of bytes for the information field. - // - - FileNameBytes += SeparatorBytes + VersionStringBytes; - - // - // Update the information with the number of bytes stored in the - // buffer. We quad-align the existing buffer to add any necessary - // pad bytes. - // - - Information = NextEntry + BaseLength + FileNameBytes; - - // - // Go back to the previous entry and fill in the update to this entry. - // - - *(Add2Ptr( UserBuffer, LastEntry, PULONG )) = NextEntry - LastEntry; - - // - // Set up our variables for the next dirent. - // - - InitialQuery = FALSE; - - LastEntry = NextEntry; - NextEntry = QuadAlign( Information ); - - } except (EXCEPTION_EXECUTE_HANDLER) { - - // - // We had a problem filling in the user's buffer, so stop and - // fail this request. This is the only reason any exception - // would have occured at this level. - // - - Information = 0; - try_leave( Status = GetExceptionCode()); - } - } - - DoCcbUpdate = TRUE; - - } finally { - - // - // Cleanup our search context - *before* aquiring the FCB mutex exclusive, - // else can block on threads in cdcreateinternalstream/purge which - // hold the FCB but are waiting for all maps in this stream to be released. - // - - CdCleanupFileContext( IrpContext, &FileContext ); - - // - // Now we can safely aqure the FCB mutex if we need to. - // - - if (DoCcbUpdate && !NT_ERROR( Status )) { - - // - // Update the Ccb to show the current state of the enumeration. - // - - CdLockFcb( IrpContext, Fcb ); - - Ccb->CurrentDirentOffset = ThisDirent->DirentOffset; - - ClearFlag( Ccb->Flags, CCB_FLAG_ENUM_RETURN_NEXT ); - - if (ReturnNextEntry) { - - SetFlag( Ccb->Flags, CCB_FLAG_ENUM_RETURN_NEXT ); - } - - CdUnlockFcb( IrpContext, Fcb ); - } - - // - // Release the Fcb. - // - - CdReleaseFile( IrpContext, Fcb ); - } - - // - // Complete the request here. - // - - Irp->IoStatus.Information = Information; - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; -} - - -// -// Local support routines -// - -NTSTATUS -CdNotifyChangeDirectory ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PIO_STACK_LOCATION IrpSp, - IN PCCB Ccb - ) - -/*++ - -Routine Description: - - This routine performs the notify change directory operation. It is - responsible for either completing of enqueuing the input Irp. Although there - will never be a notify signalled on a CDROM disk we still support this call. - - We have already checked that this is not an OpenById handle. - -Arguments: - - Irp - Supplies the Irp to process - - IrpSp - Io stack location for this request. - - Ccb - Handle to the directory being watched. - -Return Value: - - NTSTATUS - STATUS_PENDING, any other error will raise. - ---*/ - -{ - PAGED_CODE(); - - // - // Always set the wait bit in the IrpContext so the initial wait can't fail. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); - - // - // Acquire the Vcb shared. - // - - CdAcquireVcbShared( IrpContext, IrpContext->Vcb, FALSE ); - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Verify the Vcb. - // - - CdVerifyVcb( IrpContext, IrpContext->Vcb ); - - // - // Call the Fsrtl package to process the request. We cast the - // unicode strings to ansi strings as the dir notify package - // only deals with memory matching. - // - - FsRtlNotifyFullChangeDirectory( IrpContext->Vcb->NotifySync, - &IrpContext->Vcb->DirNotifyList, - Ccb, - (PSTRING) &IrpSp->FileObject->FileName, - BooleanFlagOn( IrpSp->Flags, SL_WATCH_TREE ), - FALSE, - IrpSp->Parameters.NotifyDirectory.CompletionFilter, - Irp, - NULL, - NULL ); - - } finally { - - // - // Release the Vcb. - // - - CdReleaseVcb( IrpContext, IrpContext->Vcb ); - } - - // - // Cleanup the IrpContext. - // - - CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); - - return STATUS_PENDING; -} - - -// -// Local support routine -// - -VOID -CdInitializeEnumeration ( - IN PIRP_CONTEXT IrpContext, - IN PIO_STACK_LOCATION IrpSp, - IN PFCB Fcb, - IN OUT PCCB Ccb, - IN OUT PFILE_ENUM_CONTEXT FileContext, - OUT PBOOLEAN ReturnNextEntry, - OUT PBOOLEAN ReturnSingleEntry, - OUT PBOOLEAN InitialQuery - ) - -/*++ - -Routine Description: - - This routine is called to initialize the enumeration variables and structures. - We look at the state of a previous enumeration from the Ccb as well as any - input values from the user. On exit we will position the FileContext at - a file in the directory and let the caller know whether this entry or the - next entry should be returned. - -Arguments: - - IrpSp - Irp stack location for this request. - - Fcb - Fcb for this directory. - - Ccb - Ccb for the directory handle. - - FileContext - FileContext to use for this enumeration. - - ReturnNextEntry - Address to store whether we should return the entry at - the FileContext position or the next entry. - - ReturnSingleEntry - Address to store whether we should only return - a single entry. - - InitialQuery - Address to store whether this is the first enumeration - query on this handle. - -Return Value: - - None. - ---*/ - -{ - NTSTATUS Status; - - PUNICODE_STRING FileName; - CD_NAME WildCardName; - CD_NAME SearchExpression; - - ULONG CcbFlags; - - ULONG DirentOffset; - ULONG LastDirentOffset; - BOOLEAN KnownOffset; - - BOOLEAN Found; - - PAGED_CODE(); - - // - // If this is the initial query then build a search expression from the input - // file name. - // - - if (!FlagOn( Ccb->Flags, CCB_FLAG_ENUM_INITIALIZED )) { - - FileName = IrpSp->Parameters.QueryDirectory.FileName; - - CcbFlags = 0; - - // - // If the filename is not specified or is a single '*' then we will - // match all names. - // - - if ((FileName == NULL) || - (FileName->Buffer == NULL) || - (FileName->Length == 0) || - ((FileName->Length == sizeof( WCHAR )) && - (FileName->Buffer[0] == L'*'))) { - - SetFlag( CcbFlags, CCB_FLAG_ENUM_MATCH_ALL ); - RtlZeroMemory( &SearchExpression, sizeof( SearchExpression )); - - // - // Otherwise build the CdName from the name in the stack location. - // This involves building both the name and version portions and - // checking for wild card characters. We also upcase the string if - // this is a case-insensitive search. - // - - } else { - - // - // Create a CdName to check for wild cards. - // - - WildCardName.FileName = *FileName; - - CdConvertNameToCdName( IrpContext, &WildCardName ); - - // - // The name better have at least one character. - // - - if (WildCardName.FileName.Length == 0) { - - CdRaiseStatus( IrpContext, STATUS_INVALID_PARAMETER ); - } - - // - // Check for wildcards in the separate components. - // - - if (FsRtlDoesNameContainWildCards( &WildCardName.FileName)) { - - SetFlag( CcbFlags, CCB_FLAG_ENUM_NAME_EXP_HAS_WILD ); - } - - if ((WildCardName.VersionString.Length != 0) && - (FsRtlDoesNameContainWildCards( &WildCardName.VersionString ))) { - - SetFlag( CcbFlags, CCB_FLAG_ENUM_VERSION_EXP_HAS_WILD ); - - // - // Check if this is a wild card only and match all version - // strings. - // - - if ((WildCardName.VersionString.Length == sizeof( WCHAR )) && - (WildCardName.VersionString.Buffer[0] == L'*')) { - - SetFlag( CcbFlags, CCB_FLAG_ENUM_VERSION_MATCH_ALL ); - } - } - - // - // Now create the search expression to store in the Ccb. - // - - SearchExpression.FileName.Buffer = FsRtlAllocatePoolWithTag( CdPagedPool, - FileName->Length, - TAG_ENUM_EXPRESSION ); - - SearchExpression.FileName.MaximumLength = FileName->Length; - - // - // Either copy the name directly or perform the upcase. - // - - if (FlagOn( Ccb->Flags, CCB_FLAG_IGNORE_CASE )) { - - Status = RtlUpcaseUnicodeString( (PUNICODE_STRING) &SearchExpression.FileName, - FileName, - FALSE ); - - // - // This should never fail. - // - - ASSERT( Status == STATUS_SUCCESS ); - - } else { - - RtlCopyMemory( SearchExpression.FileName.Buffer, - FileName->Buffer, - FileName->Length ); - } - - // - // Now split into the separate name and version components. - // - - SearchExpression.FileName.Length = WildCardName.FileName.Length; - SearchExpression.VersionString.Length = WildCardName.VersionString.Length; - SearchExpression.VersionString.MaximumLength = WildCardName.VersionString.MaximumLength; - - SearchExpression.VersionString.Buffer = Add2Ptr( SearchExpression.FileName.Buffer, - SearchExpression.FileName.Length + sizeof( WCHAR ), - PWCHAR ); - } - - // - // But we do not want to return the constant "." and ".." entries for - // the root directory, for consistency with the rest of Microsoft's - // filesystems. - // - - if (Fcb == Fcb->Vcb->RootIndexFcb) { - - SetFlag( CcbFlags, CCB_FLAG_ENUM_NOMATCH_CONSTANT_ENTRY ); - } - - // - // Now lock the Fcb in order to update the Ccb with the inital - // enumeration values. - // - - CdLockFcb( IrpContext, Fcb ); - - // - // Check again that this is the initial search. - // - - if (!FlagOn( Ccb->Flags, CCB_FLAG_ENUM_INITIALIZED )) { - - // - // Update the values in the Ccb. - // - - Ccb->CurrentDirentOffset = Fcb->StreamOffset; - Ccb->SearchExpression = SearchExpression; - - // - // Set the appropriate flags in the Ccb. - // - - SetFlag( Ccb->Flags, CcbFlags | CCB_FLAG_ENUM_INITIALIZED ); - - // - // Otherwise cleanup any buffer allocated here. - // - - } else { - - if (!FlagOn( CcbFlags, CCB_FLAG_ENUM_MATCH_ALL )) { - - CdFreePool( &SearchExpression.FileName.Buffer ); - } - } - - // - // Otherwise lock the Fcb so we can read the current enumeration values. - // - - } else { - - CdLockFcb( IrpContext, Fcb ); - } - - // - // Capture the current state of the enumeration. - // - // If the user specified an index then use his offset. We always - // return the next entry in this case. - // - - if (FlagOn( IrpSp->Flags, SL_INDEX_SPECIFIED )) { - - KnownOffset = FALSE; - DirentOffset = IrpSp->Parameters.QueryDirectory.FileIndex; - *ReturnNextEntry = TRUE; - - // - // If we are restarting the scan then go from the self entry. - // - - } else if (FlagOn( IrpSp->Flags, SL_RESTART_SCAN )) { - - KnownOffset = TRUE; - DirentOffset = Fcb->StreamOffset; - *ReturnNextEntry = FALSE; - - // - // Otherwise use the values from the Ccb. - // - - } else { - - KnownOffset = TRUE; - DirentOffset = Ccb->CurrentDirentOffset; - *ReturnNextEntry = BooleanFlagOn( Ccb->Flags, CCB_FLAG_ENUM_RETURN_NEXT ); - } - - // - // Unlock the Fcb. - // - - CdUnlockFcb( IrpContext, Fcb ); - - // - // We have the starting offset in the directory and whether to return - // that entry or the next. If we are at the beginning of the directory - // and are returning that entry, then tell our caller this is the - // initial query. - // - - *InitialQuery = FALSE; - - if ((DirentOffset == Fcb->StreamOffset) && - !(*ReturnNextEntry)) { - - *InitialQuery = TRUE; - } - - // - // If there is no file object then create it now. - // - - if (Fcb->FileObject == NULL) { - - CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb ); - } - - // - // Determine the offset in the stream to position the FileContext and - // whether this offset is known to be a file offset. - // - // If this offset is known to be safe then go ahead and position the - // file context. This handles the cases where the offset is the beginning - // of the stream, the offset is from a previous search or this is the - // initial query. - // - - if (KnownOffset) { - - CdLookupInitialFileDirent( IrpContext, Fcb, FileContext, DirentOffset ); - - // - // Otherwise we walk through the directory from the beginning until - // we reach the entry which contains this offset. - // - - } else { - - LastDirentOffset = Fcb->StreamOffset; - Found = TRUE; - - CdLookupInitialFileDirent( IrpContext, Fcb, FileContext, LastDirentOffset ); - - // - // If the requested offset is prior to the beginning offset in the stream - // then don't return the next entry. - // - - if (DirentOffset < LastDirentOffset) { - - *ReturnNextEntry = FALSE; - - // - // Else look for the last entry which ends past the desired index. - // - - } else { - - // - // Keep walking through the directory until we run out of - // entries or we find an entry which ends beyond the input - // index value. - // - - do { - - // - // If we have passed the index value then exit. - // - - if (FileContext->InitialDirent->Dirent.DirentOffset > DirentOffset) { - - Found = FALSE; - break; - } - - // - // Remember the current position in case we need to go back. - // - - LastDirentOffset = FileContext->InitialDirent->Dirent.DirentOffset; - - // - // Exit if the next entry is beyond the desired index value. - // - - if (LastDirentOffset + FileContext->InitialDirent->Dirent.DirentLength > DirentOffset) { - - break; - } - - Found = CdLookupNextInitialFileDirent( IrpContext, Fcb, FileContext ); - - } while (Found); - - // - // If we didn't find the entry then go back to the last known entry. - // This can happen if the index lies in the unused range at the - // end of a sector. - // - - if (!Found) { - - CdCleanupFileContext( IrpContext, FileContext ); - CdInitializeFileContext( IrpContext, FileContext ); - - CdLookupInitialFileDirent( IrpContext, Fcb, FileContext, LastDirentOffset ); - } - } - } - - // - // Only update the dirent name if we will need it for some reason. - // Don't update this name if we are returning the next entry and - // the search string has a version component. - // - - FileContext->ShortName.FileName.Length = 0; - - if (!(*ReturnNextEntry) || - (Ccb->SearchExpression.VersionString.Length == 0)) { - - // - // Update the name in the dirent into filename and version components. - // - - CdUpdateDirentName( IrpContext, - &FileContext->InitialDirent->Dirent, - FlagOn( Ccb->Flags, CCB_FLAG_IGNORE_CASE )); - } - - // - // Look at the flag in the IrpSp indicating whether to return just - // one entry. - // - - *ReturnSingleEntry = FALSE; - - if (FlagOn( IrpSp->Flags, SL_RETURN_SINGLE_ENTRY )) { - - *ReturnSingleEntry = TRUE; - } - - return; -} - - -// -// Local support routine -// - -BOOLEAN -CdEnumerateIndex ( - IN PIRP_CONTEXT IrpContext, - IN PCCB Ccb, - IN OUT PFILE_ENUM_CONTEXT FileContext, - IN BOOLEAN ReturnNextEntry - ) - -/*++ - -Routine Description: - - This routine is the worker routine for index enumeration. We are positioned - at some dirent in the directory and will either return the first match - at that point or look to the next entry. The Ccb contains details about - the type of matching to do. If the user didn't specify a version in - his search string then we only return the first version of a sequence - of files with versions. We also don't return any associated files. - -Arguments: - - Ccb - Ccb for this directory handle. - - FileContext - File context already positioned at some entry in the directory. - - ReturnNextEntry - Indicates if we are returning this entry or should start - with the next entry. - -Return Value: - - BOOLEAN - TRUE if next entry is found, FALSE otherwise. - ---*/ - -{ - PDIRENT PreviousDirent = NULL; - PDIRENT ThisDirent = &FileContext->InitialDirent->Dirent; - - BOOLEAN Found = FALSE; - - PAGED_CODE(); - - // - // Loop until we find a match or exaust the directory. - // - - while (TRUE) { - - // - // Move to the next entry unless we want to consider the current - // entry. - // - - if (ReturnNextEntry) { - - if (!CdLookupNextInitialFileDirent( IrpContext, Ccb->Fcb, FileContext )) { - - break; - } - - PreviousDirent = ThisDirent; - ThisDirent = &FileContext->InitialDirent->Dirent; - - CdUpdateDirentName( IrpContext, ThisDirent, FlagOn( Ccb->Flags, CCB_FLAG_IGNORE_CASE )); - - } else { - - ReturnNextEntry = TRUE; - } - - // - // Don't bother if we have a constant entry and are ignoring them. - // - - if (FlagOn( ThisDirent->Flags, DIRENT_FLAG_CONSTANT_ENTRY ) && - FlagOn( Ccb->Flags, CCB_FLAG_ENUM_NOMATCH_CONSTANT_ENTRY )) { - - continue; - } - - // - // Look at the current entry if it is not an associated file - // and the name doesn't match the previous file if the version - // name is not part of the search. - // - - if (!FlagOn( ThisDirent->DirentFlags, CD_ATTRIBUTE_ASSOC )) { - - // - // Check if this entry matches the previous entry except - // for version number and whether we should return the - // entry in that case. Go directly to the name comparison - // if: - // - // There is no previous entry. - // The search expression has a version component. - // The name length doesn't match the length of the previous entry. - // The base name strings don't match. - // - - if ((PreviousDirent == NULL) || - (Ccb->SearchExpression.VersionString.Length != 0) || - (PreviousDirent->CdCaseFileName.FileName.Length != ThisDirent->CdCaseFileName.FileName.Length) || - FlagOn( PreviousDirent->DirentFlags, CD_ATTRIBUTE_ASSOC ) || - !RtlEqualMemory( PreviousDirent->CdCaseFileName.FileName.Buffer, - ThisDirent->CdCaseFileName.FileName.Buffer, - ThisDirent->CdCaseFileName.FileName.Length )) { - - // - // If we match all names then return to our caller. - // - - if (FlagOn( Ccb->Flags, CCB_FLAG_ENUM_MATCH_ALL )) { - - FileContext->ShortName.FileName.Length = 0; - Found = TRUE; - break; - } - - // - // Check if the long name matches the search expression. - // - - if (CdIsNameInExpression( IrpContext, - &ThisDirent->CdCaseFileName, - &Ccb->SearchExpression, - Ccb->Flags, - TRUE )) { - - // - // Let our caller know we found an entry. - // - - Found = TRUE; - FileContext->ShortName.FileName.Length = 0; - break; - } - - // - // The long name didn't match so we need to check for a - // possible short name match. There is no match if the - // long name is 8dot3 or the search expression has a - // version component. Special case the self and parent - // entries. - // - - if ((Ccb->SearchExpression.VersionString.Length == 0) && - !FlagOn( ThisDirent->Flags, DIRENT_FLAG_CONSTANT_ENTRY ) && - !CdIs8dot3Name( IrpContext, - ThisDirent->CdFileName.FileName )) { - - CdGenerate8dot3Name( IrpContext, - &ThisDirent->CdCaseFileName.FileName, - ThisDirent->DirentOffset, - FileContext->ShortName.FileName.Buffer, - &FileContext->ShortName.FileName.Length ); - - // - // Check if this name matches. - // - - if (CdIsNameInExpression( IrpContext, - &FileContext->ShortName, - &Ccb->SearchExpression, - Ccb->Flags, - FALSE )) { - - // - // Let our caller know we found an entry. - // - - Found = TRUE; - break; - } - } - } - } - } - - // - // If we found the entry then make sure we walk through all of the - // file dirents. - // - - if (Found) { - - CdLookupLastFileDirent( IrpContext, Ccb->Fcb, FileContext ); - } - - return Found; -} - - diff --git a/reactos/drivers/filesystems/cdfs_new/dirsup.c b/reactos/drivers/filesystems/cdfs_new/dirsup.c deleted file mode 100755 index 6edfc1b8fad..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/dirsup.c +++ /dev/null @@ -1,1863 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - DirSup.c - -Abstract: - - This module implements the dirent support routines for Cdfs. - - Directories on a CD consist of a number of contiguous sectors on - the disk. File descriptors consist of one or more directory entries - (dirents) within a directory. Files may contain version numbers. If - present all like-named files will be ordered contiguously in the - directory by decreasing version numbers. We will only return the - first of these on a directory query unless the user explicitly - asks for version numbers. Finally dirents will not span sector - boundaries. Unused bytes at the end of a sector will be zero - filled. - - Directory sector: Offset - 2048 - +---------------------------------------------------------------+ - | | | | | | | - | foo;4 | foo;4 | foo;3 | hat | zebra | Zero| - | | | | | | Fill| - | | final | single | | | | - | | extent | extent | | | | - +---------------------------------------------------------------+ - - Dirent operations: - - - Position scan at known offset in directory. Dirent at this - offset must exist and is valid. Used when scanning a directory - from the beginning when the self entry is known to be valid. - Used when positioning at the first dirent for an open - file to scan the allocation information. Used when resuming - a directory enumeration from a valid directory entry. - - - Position scan at known offset in directory. Dirent is known to - start at this position but must be checked for validity. - Used to read the self-directory entry. - - - Move to the next dirent within a directory. - - - Given a known starting dirent, collect all the dirents for - that file. Scan will finish positioned at the last dirent - for the file. We will accumulate the extent lengths to - find the size of the file. - - - Given a known starting dirent, position the scan for the first - dirent of the following file. Used when not interested in - all of the details for the current file and are looking for - the next file. - - - Update a common dirent structure with the details of the on-disk - structure. This is used to smooth out the differences - - - Build the filename (name and version strings) out of the stream - of bytes in the file name on disk. For Joliet disks we will have - to convert to little endian. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_DIRSUP) - -// -// Local macros -// - -// -// PRAW_DIRENT -// CdRawDirent ( -// IN PIRP_CONTEXT IrpContext, -// IN PDIR_ENUM_CONTEXT DirContext -// ); -// - -#define CdRawDirent(IC,DC) \ - Add2Ptr( (DC)->Sector, (DC)->SectorOffset, PRAW_DIRENT ) - -// -// Local support routines -// - -ULONG -CdCheckRawDirentBounds ( - IN PIRP_CONTEXT IrpContext, - IN PDIRENT_ENUM_CONTEXT DirContext - ); - -XA_EXTENT_TYPE -CdCheckForXAExtent ( - IN PIRP_CONTEXT IrpContext, - IN PRAW_DIRENT RawDirent, - IN OUT PDIRENT Dirent - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCheckForXAExtent) -#pragma alloc_text(PAGE, CdCheckRawDirentBounds) -#pragma alloc_text(PAGE, CdCleanupFileContext) -#pragma alloc_text(PAGE, CdFindFile) -#pragma alloc_text(PAGE, CdFindDirectory) -#pragma alloc_text(PAGE, CdFindFileByShortName) -#pragma alloc_text(PAGE, CdLookupDirent) -#pragma alloc_text(PAGE, CdLookupLastFileDirent) -#pragma alloc_text(PAGE, CdLookupNextDirent) -#pragma alloc_text(PAGE, CdLookupNextInitialFileDirent) -#pragma alloc_text(PAGE, CdUpdateDirentFromRawDirent) -#pragma alloc_text(PAGE, CdUpdateDirentName) -#endif - - -VOID -CdLookupDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN ULONG DirentOffset, - OUT PDIRENT_ENUM_CONTEXT DirContext - ) - -/*++ - -Routine Description: - - This routine is called to initiate a walk through a directory. We will - position ourselves in the directory at offset DirentOffset. We know that - a dirent begins at this boundary but may have to verify the dirent bounds. - We will call this routine when looking up the first entry of a known - file or verifying the self entry of a directory. - -Arguments: - - Fcb - Fcb for the directory being traversed. - - DirentOffset - This is our target point in the directory. We will map the - page containing this entry and possibly verify the dirent bounds at - this location. - - DirContext - This is the dirent context for this scan. We update it with - the location of the dirent we found. This structure has been initialized - outside of this call. - -Return Value: - - None. - ---*/ - -{ - LONGLONG BaseOffset; - - PAGED_CODE(); - - // - // Initialize the offset of the first dirent we want to map. - // - - DirContext->BaseOffset = SectorTruncate( DirentOffset ); - BaseOffset = DirContext->BaseOffset; - - DirContext->DataLength = SECTOR_SIZE; - - DirContext->SectorOffset = SectorOffset( DirentOffset ); - - // - // Truncate the data length if we are at the end of the file. - // - - if (DirContext->DataLength > (Fcb->FileSize.QuadPart - BaseOffset)) { - - DirContext->DataLength = (ULONG) (Fcb->FileSize.QuadPart - BaseOffset); - } - - // - // Now map the data at this offset. - // - - CcMapData( Fcb->FileObject, - (PLARGE_INTEGER) &BaseOffset, - DirContext->DataLength, - TRUE, - &DirContext->Bcb, - &DirContext->Sector ); - - // - // Verify the dirent bounds. - // - - DirContext->NextDirentOffset = CdCheckRawDirentBounds( IrpContext, - DirContext ); - - return; -} - - -BOOLEAN -CdLookupNextDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PDIRENT_ENUM_CONTEXT CurrentDirContext, - OUT PDIRENT_ENUM_CONTEXT NextDirContext - ) - -/*++ - -Routine Description: - - This routine is called to find the next dirent in the directory. The - current position is given and we look for the next. We leave the context - for the starting position untouched and update the context for the - dirent we found. The target context may already be initialized so we - may already have the sector in memory. - - This routine will position the enumeration context for the next dirent and - verify the dirent bounds. - - NOTE - This routine can be called with CurrentDirContext and NextDirContext - pointing to the same enumeration context. - -Arguments: - - Fcb - Fcb for the directory being traversed. - - CurrentDirContext - This is the dirent context for this scan. We update - it with the location of the dirent we found. This is currently - pointing to a dirent location. The dirent bounds at this location - have already been verified. - - NextDirContext - This is the dirent context to update with the dirent we - find. This may already point to a dirent so we need to check if - we are in the same sector and unmap any buffer as necessary. - - This dirent is left in an indeterminant state if we don't find a dirent. - -Return Value: - - BOOLEAN - TRUE if we find a location for the next dirent, FALSE otherwise. - This routine can cause a raise if the directory is corrupt. - ---*/ - -{ - LONGLONG CurrentBaseOffset = CurrentDirContext->BaseOffset; - ULONG TempUlong; - - BOOLEAN FoundDirent = FALSE; - - PAGED_CODE(); - - // - // Check if a different sector is mapped. If so then move our target - // enumeration context to the same sector. - // - - if ((CurrentDirContext->BaseOffset != NextDirContext->BaseOffset) || - (NextDirContext->Bcb == NULL)) { - - // - // Unpin the current target Bcb and map the next sector. - // - - CdUnpinData( IrpContext, &NextDirContext->Bcb ); - - CcMapData( Fcb->FileObject, - (PLARGE_INTEGER) &CurrentBaseOffset, - CurrentDirContext->DataLength, - TRUE, - &NextDirContext->Bcb, - &NextDirContext->Sector ); - - // - // Copy the data length and sector offset. - // - - NextDirContext->DataLength = CurrentDirContext->DataLength; - NextDirContext->BaseOffset = CurrentDirContext->BaseOffset; - } - - // - // Now move to the same offset in the sector. - // - - NextDirContext->SectorOffset = CurrentDirContext->SectorOffset; - - // - // If the value is zero then unmap the current sector and set up - // the base offset to the beginning of the next sector. - // - - if (CurrentDirContext->NextDirentOffset == 0) { - - CurrentBaseOffset = NextDirContext->BaseOffset + NextDirContext->DataLength; - - // - // Unmap the current sector. We test the value of the Bcb in the - // loop below to see if we need to read in another sector. - // - - CdUnpinData( IrpContext, &NextDirContext->Bcb ); - - // - // There is another possible dirent in the current sector. Update the - // enumeration context to reflect this. - // - - } else { - - NextDirContext->SectorOffset += CurrentDirContext->NextDirentOffset; - } - - // - // Now loop until we find the next possible dirent or walk off the directory. - // - - while (TRUE) { - - // - // If we don't currently have a sector mapped then map the - // directory at the current offset. - // - - if (NextDirContext->Bcb == NULL) { - - TempUlong = SECTOR_SIZE; - - if (TempUlong > (ULONG) (Fcb->FileSize.QuadPart - CurrentBaseOffset)) { - - TempUlong = (ULONG) (Fcb->FileSize.QuadPart - CurrentBaseOffset); - - // - // If the length is zero then there is no dirent. - // - - if (TempUlong == 0) { - - break; - } - } - - CcMapData( Fcb->FileObject, - (PLARGE_INTEGER) &CurrentBaseOffset, - TempUlong, - TRUE, - &NextDirContext->Bcb, - &NextDirContext->Sector ); - - NextDirContext->BaseOffset = (ULONG) CurrentBaseOffset; - NextDirContext->SectorOffset = 0; - NextDirContext->DataLength = TempUlong; - } - - // - // The CDFS spec allows for sectors in a directory to contain all zeroes. - // In this case we need to move to the next sector. So look at the - // current potential dirent for a zero length. Move to the next - // dirent if length is zero. - // - - if (*((PCHAR) CdRawDirent( IrpContext, NextDirContext )) != 0) { - - FoundDirent = TRUE; - break; - } - - CurrentBaseOffset = NextDirContext->BaseOffset + NextDirContext->DataLength; - CdUnpinData( IrpContext, &NextDirContext->Bcb ); - } - - // - // Check the dirent bounds if we found a dirent. - // - - if (FoundDirent) { - - NextDirContext->NextDirentOffset = CdCheckRawDirentBounds( IrpContext, - NextDirContext ); - } - - return FoundDirent; -} - - -VOID -CdUpdateDirentFromRawDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PDIRENT_ENUM_CONTEXT DirContext, - IN OUT PDIRENT Dirent - ) - -/*++ - -Routine Description: - - This routine is called to safely copy the data from the dirent on disk - to the in-memory dirent. The fields on disk are unaligned so we - need to safely copy them to our structure. - -Arguments: - - Fcb - Fcb for the directory being scanned. - - DirContext - Enumeration context for the raw disk dirent. - - Dirent - In-memory dirent to update. - -Return Value: - - None. - ---*/ - -{ - PRAW_DIRENT RawDirent = CdRawDirent( IrpContext, DirContext ); - - PAGED_CODE(); - - // - // Clear all of the current state flags except the flag indicating that - // we allocated a name string. - // - - ClearFlag( Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT ); - - // - // The dirent offset is the sum of the start of the sector and the - // sector offset. - // - - Dirent->DirentOffset = DirContext->BaseOffset + DirContext->SectorOffset; - - // - // Copy the dirent length from the raw dirent. - // - - Dirent->DirentLength = RawDirent->DirLen; - - // - // The starting offset on disk is computed by finding the starting - // logical block and stepping over the Xar block. - // - - CopyUchar4( &Dirent->StartingOffset, RawDirent->FileLoc ); - - Dirent->StartingOffset += RawDirent->XarLen; - - // - // Do a safe copy to get the data length. - // - - CopyUchar4( &Dirent->DataLength, RawDirent->DataLen ); - - // - // Save a pointer to the time stamps. - // - - Dirent->CdTime = (PCHAR)RawDirent->RecordTime; /* ReactOS change: GCC "pointer targets in assignment differ in signedness" */ - - // - // Copy the dirent flags. - // - - Dirent->DirentFlags = CdRawDirentFlags( IrpContext, RawDirent ); - - // - // For both the file unit and interleave skip we want to take the - // logical block count. - // - - Dirent->FileUnitSize = - Dirent->InterleaveGapSize = 0; - - if (RawDirent->IntLeaveSize != 0) { - - Dirent->FileUnitSize = RawDirent->IntLeaveSize; - Dirent->InterleaveGapSize = RawDirent->IntLeaveSkip; - } - - // - // Get the name length and remember a pointer to the start of the - // name string. We don't do any processing on the name at this - // point. - // - // Check that the name length is non-zero. - // - - if (RawDirent->FileIdLen == 0) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - Dirent->FileNameLen = RawDirent->FileIdLen; - Dirent->FileName = (PCHAR)RawDirent->FileId; /* ReactOS change: GCC "pointer targets in assignment differ in signedness" */ - - // - // If there are any remaining bytes at the end of the dirent then - // there may be a system use area. We protect ourselves from - // disks which don't pad the dirent entries correctly by using - // a fudge factor of one. All system use areas must have a length - // greater than one. Don't bother with the system use area - // if this is a directory. - // - - Dirent->XAAttributes = 0; - Dirent->XAFileNumber = 0; - Dirent->ExtentType = Form1Data; - Dirent->SystemUseOffset = 0; - - if (!FlagOn( Dirent->DirentFlags, CD_ATTRIBUTE_DIRECTORY ) && - (Dirent->DirentLength > ((FIELD_OFFSET( RAW_DIRENT, FileId ) + Dirent->FileNameLen) + 1))) { - - Dirent->SystemUseOffset = WordAlign( FIELD_OFFSET( RAW_DIRENT, FileId ) + Dirent->FileNameLen ); - } - - return; -} - - -VOID -CdUpdateDirentName ( - IN PIRP_CONTEXT IrpContext, - IN OUT PDIRENT Dirent, - IN ULONG IgnoreCase - ) - -/*++ - -Routine Description: - - This routine is called to update the name in the dirent with the name - from the disk. We will look for the special case of the self and - parent entries and also construct the Unicode name for the Joliet disk - in order to work around the BigEndian on-disk structure. - -Arguments: - - Dirent - Pointer to the in-memory dirent structure. - - IgnoreCase - TRUE if we should build the upcased version. Otherwise we - use the exact case name. - -Return Value: - - None. - ---*/ - -{ - UCHAR DirectoryValue; - ULONG Length; - - NTSTATUS Status; - - PAGED_CODE(); - - // - // Check if this is a self or parent entry. There is no version number - // in these cases. We use a fixed string for these. - // - // Self-Entry - Length is 1, value is 0. - // Parent-Entry - Length is 1, value is 1. - // - - if ((Dirent->FileNameLen == 1) && - FlagOn( Dirent->DirentFlags, CD_ATTRIBUTE_DIRECTORY )) { - - DirectoryValue = *((PCHAR) Dirent->FileName); - - if ((DirectoryValue == 0) || (DirectoryValue == 1)) { - - // - // We should not have allocated a name by the time we see these cases. - // If we have, this means that the image is in violation of ISO 9660 7.6.2, - // which states that the ./.. entries must be the first two in the directory. - // - - if (FlagOn( Dirent->Flags, DIRENT_FLAG_ALLOC_BUFFER )) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - // - // Now use one of the hard coded directory names. - // - - Dirent->CdFileName.FileName = CdUnicodeDirectoryNames[DirectoryValue]; - - // - // Show that there is no version number. - // - - Dirent->CdFileName.VersionString.Length = 0; - - // - // The case name is the same as the exact name. - // - - Dirent->CdCaseFileName = Dirent->CdFileName; - - // - // Mark this as a constant value entry. - // - - SetFlag( Dirent->Flags, DIRENT_FLAG_CONSTANT_ENTRY ); - - // - // Return now. - // - - return; - } - } - - // - // Mark this as a non-constant value entry. - // - - ClearFlag( Dirent->Flags, DIRENT_FLAG_CONSTANT_ENTRY ); - - // - // Compute how large a buffer we will need. If this is an ignore - // case operation then we will want a double size buffer. If the disk is not - // a Joliet disk then we might need two bytes for each byte in the name. - // - - Length = Dirent->FileNameLen; - - if (IgnoreCase) { - - Length *= 2; - } - - if (!FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) { - - Length *= sizeof( WCHAR ); - } - - // - // Now decide if we need to allocate a new buffer. We will if - // this name won't fit in the embedded name buffer and it is - // larger than the current allocated buffer. We always use the - // allocated buffer if present. - // - // If we haven't allocated a buffer then use the embedded buffer if the data - // will fit. This is the typical case. - // - - if (!FlagOn( Dirent->Flags, DIRENT_FLAG_ALLOC_BUFFER ) && - (Length <= sizeof( Dirent->NameBuffer ))) { - - Dirent->CdFileName.FileName.MaximumLength = sizeof( Dirent->NameBuffer ); - Dirent->CdFileName.FileName.Buffer = Dirent->NameBuffer; - - } else { - - // - // We need to use an allocated buffer. Check if the current buffer - // is large enough. - // - - if (Length > Dirent->CdFileName.FileName.MaximumLength) { - - // - // Free any allocated buffer. - // - - if (FlagOn( Dirent->Flags, DIRENT_FLAG_ALLOC_BUFFER )) { - - CdFreePool( &Dirent->CdFileName.FileName.Buffer ); - ClearFlag( Dirent->Flags, DIRENT_FLAG_ALLOC_BUFFER ); - } - - Dirent->CdFileName.FileName.Buffer = FsRtlAllocatePoolWithTag( CdPagedPool, - Length, - TAG_DIRENT_NAME ); - - SetFlag( Dirent->Flags, DIRENT_FLAG_ALLOC_BUFFER ); - - Dirent->CdFileName.FileName.MaximumLength = (USHORT) Length; - } - } - - // - // We now have a buffer for the name. We need to either convert the on-disk bigendian - // to little endian or covert the name to Unicode. - // - - if (!FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) { - - Status = RtlOemToUnicodeN( Dirent->CdFileName.FileName.Buffer, - Dirent->CdFileName.FileName.MaximumLength, - &Length, - Dirent->FileName, - Dirent->FileNameLen ); - - ASSERT( Status == STATUS_SUCCESS ); - Dirent->CdFileName.FileName.Length = (USHORT) Length; - - } else { - - // - // Convert this string to little endian. - // - - CdConvertBigToLittleEndian( IrpContext, - Dirent->FileName, - Dirent->FileNameLen, - (PCHAR) Dirent->CdFileName.FileName.Buffer ); - - Dirent->CdFileName.FileName.Length = (USHORT) Dirent->FileNameLen; - } - - // - // Split the name into name and version strings. - // - - CdConvertNameToCdName( IrpContext, - &Dirent->CdFileName ); - - // - // The name length better be non-zero. - // - - if (Dirent->CdFileName.FileName.Length == 0) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - // - // If the filename ends with a period then back up one character. - // - - if (Dirent->CdFileName.FileName.Buffer[(Dirent->CdFileName.FileName.Length - sizeof( WCHAR )) / 2] == L'.') { - - // - // Slide the version string down. - // - - if (Dirent->CdFileName.VersionString.Length != 0) { - - PWCHAR NewVersion; - - // - // Start from the position currently containing the separator. - // - - NewVersion = Add2Ptr( Dirent->CdFileName.FileName.Buffer, - Dirent->CdFileName.FileName.Length, - PWCHAR ); - - // - // Now overwrite the period. - // - - RtlMoveMemory( NewVersion - 1, - NewVersion, - Dirent->CdFileName.VersionString.Length + sizeof( WCHAR )); - - // - // Now point to the new version string. - // - - Dirent->CdFileName.VersionString.Buffer = NewVersion; - } - - // - // Shrink the filename length. - // - - Dirent->CdFileName.FileName.Length -= sizeof( WCHAR ); - } - - // - // If this an exact case operation then use the filename exactly. - // - - if (!IgnoreCase) { - - Dirent->CdCaseFileName = Dirent->CdFileName; - - // - // Otherwise perform our upcase operation. We already have guaranteed the buffers are - // there. - // - - } else { - - Dirent->CdCaseFileName.FileName.Buffer = Add2Ptr( Dirent->CdFileName.FileName.Buffer, - Dirent->CdFileName.FileName.MaximumLength / 2, - PWCHAR); - - Dirent->CdCaseFileName.FileName.MaximumLength = Dirent->CdFileName.FileName.MaximumLength / 2; - - CdUpcaseName( IrpContext, - &Dirent->CdFileName, - &Dirent->CdCaseFileName ); - } - - return; -} - - -BOOLEAN -CdFindFile ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PCD_NAME Name, - IN BOOLEAN IgnoreCase, - IN OUT PFILE_ENUM_CONTEXT FileContext, - OUT PCD_NAME *MatchingName - ) - -/*++ - -Routine Description: - - This routine is called to search a dirctory for a file matching the input - name. This name has been upcased at this point if this a case-insensitive - search. The name has been separated into separate name and version strings. - We look for an exact match in the name and only consider the version if - there is a version specified in the search name. - -Arguments: - - Fcb - Fcb for the directory being scanned. - - Name - Name to search for. - - IgnoreCase - Indicates the case of the search. - - FileContext - File context to use for the search. This has already been - initialized. - - MatchingName - Pointer to buffer containing matching name. We need this - in case we don't match the name in the directory but match the - short name instead. - -Return Value: - - BOOLEAN - TRUE if matching entry is found, FALSE otherwise. - ---*/ - -{ - PDIRENT Dirent; - ULONG ShortNameDirentOffset; - - BOOLEAN Found = FALSE; - - PAGED_CODE(); - - // - // Make sure there is a stream file for this Fcb. - // - - if (Fcb->FileObject == NULL) { - - CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb ); - } - - // - // Check to see whether we need to check for a possible short name. - // - - ShortNameDirentOffset = CdShortNameDirentOffset( IrpContext, &Name->FileName ); - - // - // Position ourselves at the first entry. - // - - CdLookupInitialFileDirent( IrpContext, Fcb, FileContext, Fcb->StreamOffset ); - - // - // Loop while there are more entries in this directory. - // - - do { - - Dirent = &FileContext->InitialDirent->Dirent; - - // - // We only consider files which don't have the associated bit set. - // We also only look for files. All directories would already - // have been found. - // - - if (!FlagOn( Dirent->DirentFlags, CD_ATTRIBUTE_ASSOC | CD_ATTRIBUTE_DIRECTORY )) { - - // - // Update the name in the current dirent. - // - - CdUpdateDirentName( IrpContext, Dirent, IgnoreCase ); - - // - // Don't bother with constant entries. - // - - if (FlagOn( Dirent->Flags, DIRENT_FLAG_CONSTANT_ENTRY )) { - - continue; - } - - // - // Now check whether we have a name match. - // We exit the loop if we have a match. - // - - if (CdIsNameInExpression( IrpContext, - &Dirent->CdCaseFileName, - Name, - 0, - TRUE )) { - - *MatchingName = &Dirent->CdCaseFileName; - Found = TRUE; - break; - } - - // - // The names didn't match. If the input name is a possible short - // name and we are at the correct offset in the directory then - // check if the short names match. - // - - if (((Dirent->DirentOffset >> SHORT_NAME_SHIFT) == ShortNameDirentOffset) && - (Name->VersionString.Length == 0) && - !CdIs8dot3Name( IrpContext, - Dirent->CdFileName.FileName )) { - - // - // Create the short name and check for a match. - // - - CdGenerate8dot3Name( IrpContext, - &Dirent->CdCaseFileName.FileName, - Dirent->DirentOffset, - FileContext->ShortName.FileName.Buffer, - &FileContext->ShortName.FileName.Length ); - - // - // Now check whether we have a name match. - // We exit the loop if we have a match. - // - - if (CdIsNameInExpression( IrpContext, - &FileContext->ShortName, - Name, - 0, - FALSE )) { - - *MatchingName = &FileContext->ShortName, - Found = TRUE; - break; - } - } - } - - // - // Go to the next initial dirent for a file. - // - - } while (CdLookupNextInitialFileDirent( IrpContext, Fcb, FileContext )); - - // - // If we find the file then collect all of the dirents. - // - - if (Found) { - - CdLookupLastFileDirent( IrpContext, Fcb, FileContext ); - - } - - return Found; -} - - -BOOLEAN -CdFindDirectory ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PCD_NAME Name, - IN BOOLEAN IgnoreCase, - IN OUT PFILE_ENUM_CONTEXT FileContext - ) - -/*++ - -Routine Description: - - This routine is called to search a dirctory for a directory matching the input - name. This name has been upcased at this point if this a case-insensitive - search. We look for an exact match in the name and do not look for shortname - equivalents. - -Arguments: - - Fcb - Fcb for the directory being scanned. - - Name - Name to search for. - - IgnoreCase - Indicates the case of the search. - - FileContext - File context to use for the search. This has already been - initialized. - -Return Value: - - BOOLEAN - TRUE if matching entry is found, FALSE otherwise. - ---*/ - -{ - PDIRENT Dirent; - - BOOLEAN Found = FALSE; - - PAGED_CODE(); - - // - // Make sure there is a stream file for this Fcb. - // - - if (Fcb->FileObject == NULL) { - - CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb ); - } - - // - // Position ourselves at the first entry. - // - - CdLookupInitialFileDirent( IrpContext, Fcb, FileContext, Fcb->StreamOffset ); - - // - // Loop while there are more entries in this directory. - // - - do { - - Dirent = &FileContext->InitialDirent->Dirent; - - // - // We only look for directories. Directories cannot have the - // associated bit set. - // - - if (FlagOn( Dirent->DirentFlags, CD_ATTRIBUTE_DIRECTORY )) { - - // - // Update the name in the current dirent. - // - - CdUpdateDirentName( IrpContext, Dirent, IgnoreCase ); - - // - // Don't bother with constant entries. - // - - if (FlagOn( Dirent->Flags, DIRENT_FLAG_CONSTANT_ENTRY )) { - - continue; - } - - // - // Now check whether we have a name match. - // We exit the loop if we have a match. - // - - if (CdIsNameInExpression( IrpContext, - &Dirent->CdCaseFileName, - Name, - 0, - TRUE )) { - - Found = TRUE; - break; - } - } - - // - // Go to the next initial dirent. - // - - } while (CdLookupNextInitialFileDirent( IrpContext, Fcb, FileContext )); - - return Found; -} - - -BOOLEAN -CdFindFileByShortName ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PCD_NAME Name, - IN BOOLEAN IgnoreCase, - IN ULONG ShortNameDirentOffset, - IN OUT PFILE_ENUM_CONTEXT FileContext - ) - -/*++ - -Routine Description: - - This routine is called to find the file name entry whose short name - is defined by the input DirentOffset. The dirent offset here is - multiplied by 32 and we look for the dirent begins in this 32 byte offset in - directory. The minimum dirent length is 34 so we are guaranteed that only - one dirent can begin in each 32 byte block in the directory. - -Arguments: - - Fcb - Fcb for the directory being scanned. - - Name - Name we are trying to match. We know this contains the tilde - character followed by decimal characters. - - IgnoreCase - Indicates whether we need to upcase the long name and - generated short name. - - ShortNameDirentOffset - This is the shifted value for the offset of the - name in the directory. - - FileContext - This is the initialized file context to use for the search. - -Return Value: - - BOOLEAN - TRUE if a matching name was found, FALSE otherwise. - ---*/ - -{ - BOOLEAN Found = FALSE; - PDIRENT Dirent; - - ULONG ThisShortNameDirentOffset; - - PAGED_CODE(); - - // - // Make sure there is a stream file for this Fcb. - // - - if (Fcb->FileObject == NULL) { - - CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb ); - } - - // - // Position ourselves at the start of the directory and update - // - // - - CdLookupInitialFileDirent( IrpContext, Fcb, FileContext, Fcb->StreamOffset ); - - // - // Loop until we have found the entry or are beyond this dirent. - // - - do { - - // - // Compute the short name dirent offset for the current dirent. - // - - Dirent = &FileContext->InitialDirent->Dirent; - ThisShortNameDirentOffset = Dirent->DirentOffset >> SHORT_NAME_SHIFT; - - // - // If beyond the target then exit. - // - - if (ThisShortNameDirentOffset > ShortNameDirentOffset) { - - break; - } - - // - // If equal to the target then check if we have a name match. - // We will either match or fail here. - // - - if (ThisShortNameDirentOffset == ShortNameDirentOffset) { - - // - // If this is an associated file then get out. - // - - if (FlagOn( Dirent->DirentFlags, CD_ATTRIBUTE_ASSOC )) { - - break; - } - - // - // Update the name in the dirent and check if it is not - // an 8.3 name. - // - - CdUpdateDirentName( IrpContext, Dirent, IgnoreCase ); - - if (CdIs8dot3Name( IrpContext, - Dirent->CdFileName.FileName )) { - - break; - } - - // - // Generate the 8.3 name see if it matches our input name. - // - - CdGenerate8dot3Name( IrpContext, - &Dirent->CdCaseFileName.FileName, - Dirent->DirentOffset, - FileContext->ShortName.FileName.Buffer, - &FileContext->ShortName.FileName.Length ); - - // - // Check if this name matches. - // - - if (CdIsNameInExpression( IrpContext, - Name, - &FileContext->ShortName, - 0, - FALSE )) { - - // - // Let our caller know we found an entry. - // - - Found = TRUE; - } - - // - // Break out of the loop. - // - - break; - } - - // - // Continue until there are no more entries. - // - - } while (CdLookupNextInitialFileDirent( IrpContext, Fcb, FileContext )); - - // - // If we find the file then collect all of the dirents. - // - - if (Found) { - - CdLookupLastFileDirent( IrpContext, Fcb, FileContext ); - - } - - return Found; -} - - -BOOLEAN -CdLookupNextInitialFileDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_ENUM_CONTEXT FileContext - ) - -/*++ - -Routine Description: - - This routine is called to walk through the directory until we find the - first possible dirent for file. We are positioned at some point described - by the FileContext. We will walk through any remaing dirents for the - current file until we find the first dirent for some subsequent file. - - We can be called when we have found just one dirent for a file or all - of them. We first check the CurrentDirContext. In the typical - single-extent case this is unused. Then we look to the InitialDirContext - which must be initialized. - - This routine will save the initial DirContext to the PriorDirContext and - clean up any existing DirContext for the Prior or Current positions in - the enumeration context. - -Arguments: - - Fcb - This is the directory to scan. - - FileContext - This is the file enumeration context. It is currently pointing - at some file in the directory. - -Return Value: - ---*/ - -{ - PRAW_DIRENT RawDirent; - - PDIRENT_ENUM_CONTEXT CurrentDirContext; - PDIRENT_ENUM_CONTEXT TargetDirContext; - PCOMPOUND_DIRENT TempDirent; - - BOOLEAN FoundDirent = FALSE; - BOOLEAN FoundLastDirent; - - PAGED_CODE(); - - // - // Start by saving the initial dirent of the current file as the - // previous file. - // - - TempDirent = FileContext->PriorDirent; - FileContext->PriorDirent = FileContext->InitialDirent; - FileContext->InitialDirent = TempDirent; - - // - // We will use the initial dirent of the prior file unless the - // previous search returned multiple extents. - // - - CurrentDirContext = &FileContext->PriorDirent->DirContext; - - if (FlagOn( FileContext->Flags, FILE_CONTEXT_MULTIPLE_DIRENTS )) { - - CurrentDirContext = &FileContext->CurrentDirent->DirContext; - } - - // - // Clear all of the flags and file size for the next file. - // - - FileContext->Flags = 0; - FileContext->FileSize = 0; - - FileContext->ShortName.FileName.Length = 0; - - // - // We always want to store the result into the updated initial dirent - // context. - // - - TargetDirContext = &FileContext->InitialDirent->DirContext; - - // - // Loop until we find the first dirent after the last dirent of the - // current file. We may not be at the last dirent for the current file yet - // so we may walk forward looking for the last and then find the - // initial dirent for the next file after that. - // - - while (TRUE) { - - // - // Remember if the last dirent we visited was the last dirent for - // a file. - // - - RawDirent = CdRawDirent( IrpContext, CurrentDirContext ); - - FoundLastDirent = !FlagOn( CdRawDirentFlags( IrpContext, RawDirent ), CD_ATTRIBUTE_MULTI ); - - // - // Try to find another dirent. - // - - FoundDirent = CdLookupNextDirent( IrpContext, - Fcb, - CurrentDirContext, - TargetDirContext ); - - // - // Exit the loop if no entry found. - // - - if (!FoundDirent) { - - break; - - } - - // - // Update the in-memory dirent. - // - - CdUpdateDirentFromRawDirent( IrpContext, - Fcb, - TargetDirContext, - &FileContext->InitialDirent->Dirent ); - - // - // Exit the loop if we had the end for the previous file. - // - - if (FoundLastDirent) { - - break; - } - - // - // Always use a single dirent from this point on. - // - - CurrentDirContext = TargetDirContext; - } - - return FoundDirent; -} - - -VOID -CdLookupLastFileDirent ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PFILE_ENUM_CONTEXT FileContext - ) - -/*++ - -Routine Description: - - This routine is called when we've found the matching initial dirent for - a file. Now we want to find all of the dirents for a file as well as - compute the running total for the file size. - - We also go out to the system use area and check whether this is an - XA sector. In that case we will compute the real file size. - - The dirent in the initial compound dirent has been updated from the - raw dirent when this routine is called. - -Arguments: - - Fcb - Directory containing the entries for the file. - - FileContext - Enumeration context for this search. It currently points - to the first dirent of the file and the in-memory dirent has been - updated. - -Return Value: - - None. This routine may raise STATUS_FILE_CORRUPT. - ---*/ - -{ - XA_EXTENT_TYPE ExtentType = 0; /* ReactOS Change: GCC Uninit var */ - PCOMPOUND_DIRENT CurrentCompoundDirent; - PDIRENT CurrentDirent; - - BOOLEAN FirstPass = TRUE; - BOOLEAN FoundDirent; - - PAGED_CODE(); - - // - // The current dirent to look at is the initial dirent for the file. - // - - CurrentCompoundDirent = FileContext->InitialDirent; - - // - // Loop until we reach the last dirent for the file. - // - - while (TRUE) { - - CurrentDirent = &CurrentCompoundDirent->Dirent; - - // - // Check if this extent has XA sectors. - // - - if ((CurrentDirent->SystemUseOffset != 0) && - FlagOn( Fcb->Vcb->VcbState, VCB_STATE_CDXA ) && - CdCheckForXAExtent( IrpContext, - CdRawDirent( IrpContext, &CurrentCompoundDirent->DirContext ), - CurrentDirent )) { - - // - // Any previous dirent must describe XA sectors as well. - // - - if (!FirstPass && (ExtentType != CurrentDirent->ExtentType)) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - // - // If there are XA sectors then the data on the disk must - // be correctly aligned on sectors and be an integral number of - // sectors. Only an issue if the logical block size is not - // 2048. - // - - if (Fcb->Vcb->BlockSize != SECTOR_SIZE) { - - // - // We will do the following checks. - // - // Data must start on a sector boundary. - // Data length must be integral number of sectors. - // - - if ((SectorBlockOffset( Fcb->Vcb, CurrentDirent->StartingOffset ) != 0) || - (SectorBlockOffset( Fcb->Vcb, CurrentDirent->DataLength ) != 0)) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - // - // If interleaved then both the file unit and interleave - // gap must be integral number of sectors. - // - - if ((CurrentDirent->FileUnitSize != 0) && - ((SectorBlockOffset( Fcb->Vcb, CurrentDirent->FileUnitSize ) != 0) || - (SectorBlockOffset( Fcb->Vcb, CurrentDirent->InterleaveGapSize ) != 0))) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - } - - // - // If this is the first dirent then add the bytes for the RIFF - // header. - // - - if (FirstPass) { - - FileContext->FileSize = sizeof( RIFF_HEADER ); - } - - // - // Add the size of the mode2-form2 sector for each sector - // we have here. - // - - FileContext->FileSize += Int32x32To64( CurrentDirent->DataLength >> SECTOR_SHIFT, - XA_SECTOR_SIZE); - - } else { - - // - // This extent does not have XA sectors. Any previous dirent - // better not have XA sectors. - // - - if (!FirstPass && (ExtentType != CurrentDirent->ExtentType)) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - // - // Add these bytes to the file size. - // - - FileContext->FileSize += CurrentDirent->DataLength; - } - - // - // If we are at the last dirent then exit. - // - - if (!FlagOn( CurrentDirent->DirentFlags, CD_ATTRIBUTE_MULTI )) { - - break; - } - - // - // Remember the extent type of the current extent. - // - - ExtentType = CurrentDirent->ExtentType; - - // - // Look for the next dirent of the file. - // - - FoundDirent = CdLookupNextDirent( IrpContext, - Fcb, - &CurrentCompoundDirent->DirContext, - &FileContext->CurrentDirent->DirContext ); - - // - // If we didn't find the entry then this is a corrupt directory. - // - - if (!FoundDirent) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - // - // Remember the dirent we just found. - // - - CurrentCompoundDirent = FileContext->CurrentDirent; - FirstPass = FALSE; - - // - // Look up all of the dirent information for the given dirent. - // - - CdUpdateDirentFromRawDirent( IrpContext, - Fcb, - &CurrentCompoundDirent->DirContext, - &CurrentCompoundDirent->Dirent ); - - // - // Set flag to show there were multiple extents. - // - - SetFlag( FileContext->Flags, FILE_CONTEXT_MULTIPLE_DIRENTS ); - } - - return; -} - - -VOID -CdCleanupFileContext ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_ENUM_CONTEXT FileContext - ) - -/*++ - -Routine Description: - - This routine is called to cleanup the enumeration context for a file - search in a directory. We will unpin any remaining Bcbs and free - any allocated buffers. - -Arguments: - - FileContext - Enumeration context for the file search. - -Return Value: - - None. - ---*/ - -{ - PCOMPOUND_DIRENT CurrentCompoundDirent; - ULONG Count = 2; - - PAGED_CODE(); - - // - // Cleanup the individual compound dirents. - // - - do { - - CurrentCompoundDirent = &FileContext->Dirents[ Count ]; - CdCleanupDirContext( IrpContext, &CurrentCompoundDirent->DirContext ); - CdCleanupDirent( IrpContext, &CurrentCompoundDirent->Dirent ); - - } while (Count--); - - return; -} - - -// -// Local support routine -// - -ULONG -CdCheckRawDirentBounds ( - IN PIRP_CONTEXT IrpContext, - IN PDIRENT_ENUM_CONTEXT DirContext - ) - -/*++ - -Routine Description: - - This routine takes a Dirent enumeration context and computes the offset - to the next dirent. A non-zero value indicates the offset within this - sector. A zero value indicates to move to the next sector. If the - current dirent does not fit within the sector then we will raise - STATUS_CORRUPT. - -Arguments: - - DirContext - Enumeration context indicating the current position in - the sector. - -Return Value: - - ULONG - Offset to the next dirent in this sector or zero if the - next dirent is in the next sector. - - This routine will raise on a dirent which does not fit into the - described data buffer. - ---*/ - -{ - ULONG NextDirentOffset; - PRAW_DIRENT RawDirent; - - PAGED_CODE(); - - // - // We should always have at least a byte still available in the - // current buffer. - // - - ASSERT( (DirContext->DataLength - DirContext->SectorOffset) >= 1 ); - - // - // Get a pointer to the current dirent. - // - - RawDirent = CdRawDirent( IrpContext, DirContext ); - - // - // If the dirent length is non-zero then look at the current dirent. - // - - if (RawDirent->DirLen != 0) { - - // - // Check the following bound for the dirent length. - // - // - Fits in the available bytes in the sector. - // - Is at least the minimal dirent size. - // - Is large enough to hold the file name. - // - - if ((RawDirent->DirLen > (DirContext->DataLength - DirContext->SectorOffset)) || - (RawDirent->DirLen < MIN_RAW_DIRENT_LEN) || - (RawDirent->DirLen < (MIN_RAW_DIRENT_LEN - 1 + RawDirent->FileIdLen))) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - // - // Copy the dirent length field. - // - - NextDirentOffset = RawDirent->DirLen; - - // - // If we are exactly at the next sector then tell our caller by - // returning zero. - // - - if (NextDirentOffset == (DirContext->DataLength - DirContext->SectorOffset)) { - - NextDirentOffset = 0; - } - - } else { - - NextDirentOffset = 0; - } - - return NextDirentOffset; -} - - -// -// Local support routine -// - -XA_EXTENT_TYPE -CdCheckForXAExtent ( - IN PIRP_CONTEXT IrpContext, - IN PRAW_DIRENT RawDirent, - IN OUT PDIRENT Dirent - ) - -/*++ - -Routine Description: - - This routine is called to scan through the system use area to test if - the current dirent has the XA bit set. The bit in the in-memory - dirent will be set as appropriate. - -Arguments: - - RawDirent - Pointer to the on-disk dirent. - - Dirent - Pointer to the in-memory dirent. We will update this with the - appropriate XA flag. - -Return Value: - - XA_EXTENT_TYPE - Type of physical extent for this on disk dirent. - ---*/ - -{ - XA_EXTENT_TYPE ExtentType = Form1Data; - PSYSTEM_USE_XA SystemUseArea; - - PAGED_CODE(); - - // - // Check if there is enough space for the XA system use area. - // - - if (Dirent->DirentLength - Dirent->SystemUseOffset >= sizeof( SYSTEM_USE_XA )) { - - SystemUseArea = Add2Ptr( RawDirent, Dirent->SystemUseOffset, PSYSTEM_USE_XA ); - - // - // Check for a valid signature. - // - - if (SystemUseArea->Signature == SYSTEM_XA_SIGNATURE) { - - // - // Check for an audio track. - // - - if (FlagOn( SystemUseArea->Attributes, SYSTEM_USE_XA_DA )) { - - ExtentType = CDAudio; - - } else if (FlagOn( SystemUseArea->Attributes, SYSTEM_USE_XA_FORM2 )) { - - // - // Check for XA data. Note that a number of discs (video CDs) - // have files marked as type XA Mode 2 Form 1 (2048 bytes of - // user data), but actually record these sectors as Mode2 Form 2 - // (2352). We will fail to read these files, since for M2F1, - // a normal read CD command is issued (as per SCSI specs). - // - - ExtentType = Mode2Form2Data; - } - - Dirent->XAAttributes = SystemUseArea->Attributes; - Dirent->XAFileNumber = SystemUseArea->FileNumber; - } - } - - Dirent->ExtentType = ExtentType; - return ExtentType; -} - - - diff --git a/reactos/drivers/filesystems/cdfs_new/fieldoff.c b/reactos/drivers/filesystems/cdfs_new/fieldoff.c deleted file mode 100755 index c307c108347..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/fieldoff.c +++ /dev/null @@ -1,478 +0,0 @@ -#include "CdProcs.h" -#include - -#define doit(a,b) { printf("%s %04lx %4lx %s\n", #a, FIELD_OFFSET(a,b), sizeof(d.b), #b); } - -VOID -__cdecl -main (argc, argv) - int argc; - char *argv[]; -{ - printf(" \n\n"); - { - CD_MCB d; - doit( CD_MCB, MaximumEntryCount ); - doit( CD_MCB, CurrentEntryCount ); - doit( CD_MCB, McbArray ); - } - printf("\n"); - { - CD_MCB_ENTRY d; - doit( CD_MCB_ENTRY, DiskOffset ); - doit( CD_MCB_ENTRY, ByteCount ); - doit( CD_MCB_ENTRY, FileOffset ); - doit( CD_MCB_ENTRY, DataBlockByteCount ); - doit( CD_MCB_ENTRY, TotalBlockByteCount ); - } - printf("\n"); - { - CD_NAME d; - doit( CD_NAME, FileName ); - doit( CD_NAME, VersionString ); - } - printf("\n"); - { - NAME_LINK d; - doit( NAME_LINK, Links ); - doit( NAME_LINK, FileName ); - } - printf("\n"); - { - PREFIX_ENTRY d; - doit( PREFIX_ENTRY, Fcb ); - doit( PREFIX_ENTRY, PrefixFlags ); - doit( PREFIX_ENTRY, ExactCaseName ); - doit( PREFIX_ENTRY, IgnoreCaseName ); - doit( PREFIX_ENTRY, FileNameBuffer ); - } - printf("\n"); - { - CD_DATA d; - doit( CD_DATA, NodeTypeCode ); - doit( CD_DATA, NodeByteSize ); - doit( CD_DATA, DriverObject ); - doit( CD_DATA, VcbQueue ); - doit( CD_DATA, IrpContextDepth ); - doit( CD_DATA, IrpContextMaxDepth ); - doit( CD_DATA, IrpContextList ); - doit( CD_DATA, FileSystemDeviceObject ); - doit( CD_DATA, AsyncCloseQueue ); - doit( CD_DATA, AsyncCloseCount ); - doit( CD_DATA, FspCloseActive ); - doit( CD_DATA, ReduceDelayedClose ); - doit( CD_DATA, PadUshort ); - doit( CD_DATA, DelayedCloseQueue ); - doit( CD_DATA, DelayedCloseCount ); - doit( CD_DATA, MinDelayedCloseCount ); - doit( CD_DATA, MaxDelayedCloseCount ); - doit( CD_DATA, CdDataLockThread ); - doit( CD_DATA, CdDataMutex ); - doit( CD_DATA, DataResource ); - doit( CD_DATA, CacheManagerCallbacks ); - doit( CD_DATA, CacheManagerVolumeCallbacks ); - doit( CD_DATA, CloseItem ); - } - printf("\n"); - { - VCB d; - doit( VCB, NodeTypeCode ); - doit( VCB, NodeByteSize ); - doit( VCB, Vpb ); - doit( VCB, TargetDeviceObject ); - doit( VCB, VolumeLockFileObject ); - doit( VCB, VcbLinks ); - doit( VCB, VcbState ); - doit( VCB, VcbCondition ); - doit( VCB, VcbCleanup ); - doit( VCB, VcbReference ); - doit( VCB, VcbUserReference ); - doit( VCB, VolumeDasdFcb ); - doit( VCB, RootIndexFcb ); - doit( VCB, PathTableFcb ); - doit( VCB, BaseSector ); - doit( VCB, VdSectorOffset ); - doit( VCB, PrimaryVdSectorOffset ); - doit( VCB, XASector ); - doit( VCB, XADiskOffset ); - doit( VCB, VcbResource ); - doit( VCB, FileResource ); - doit( VCB, VcbMutex ); - doit( VCB, VcbLockThread ); - doit( VCB, NotifySync ); - doit( VCB, DirNotifyList ); - doit( VCB, BlockSize ); - doit( VCB, BlockToSectorShift ); - doit( VCB, BlockToByteShift ); - doit( VCB, BlocksPerSector ); - doit( VCB, BlockMask ); - doit( VCB, BlockInverseMask ); - doit( VCB, FcbTable ); - doit( VCB, CdromToc ); - doit( VCB, TocLength ); - doit( VCB, TrackCount ); - doit( VCB, DiskFlags ); - doit( VCB, BlockFactor ); - } - printf("\n"); - { - VOLUME_DEVICE_OBJECT d; - doit( VOLUME_DEVICE_OBJECT, DeviceObject ); - doit( VOLUME_DEVICE_OBJECT, PostedRequestCount ); - doit( VOLUME_DEVICE_OBJECT, OverflowQueueCount ); - doit( VOLUME_DEVICE_OBJECT, OverflowQueue ); - doit( VOLUME_DEVICE_OBJECT, OverflowQueueSpinLock ); - doit( VOLUME_DEVICE_OBJECT, Vcb ); - } - printf("\n"); - { - FCB_DATA d; - doit( FCB_DATA, Oplock ); - doit( FCB_DATA, FileLock ); - } - printf("\n"); - { - FCB_INDEX d; - doit( FCB_INDEX, FileObject ); - doit( FCB_INDEX, StreamOffset ); - doit( FCB_INDEX, FcbQueue ); - doit( FCB_INDEX, Ordinal ); - doit( FCB_INDEX, ChildPathTableOffset ); - doit( FCB_INDEX, ChildOrdinal ); - doit( FCB_INDEX, ExactCaseRoot ); - doit( FCB_INDEX, IgnoreCaseRoot ); - } - printf("\n"); - { - FCB_NONPAGED d; - doit( FCB_NONPAGED, NodeTypeCode ); - doit( FCB_NONPAGED, NodeByteSize ); - doit( FCB_NONPAGED, SegmentObject ); - doit( FCB_NONPAGED, FcbResource ); - doit( FCB_NONPAGED, FcbMutex ); - } - printf("\n"); - { - FCB d; - doit( FCB, Header ); - doit( FCB, Vcb ); - doit( FCB, ParentFcb ); - doit( FCB, FcbLinks ); - doit( FCB, FileId ); - doit( FCB, FcbCleanup ); - doit( FCB, FcbReference ); - doit( FCB, FcbUserReference ); - doit( FCB, FcbState ); - doit( FCB, FileAttributes ); - doit( FCB, XAAttributes ); - doit( FCB, XAFileNumber ); - doit( FCB, FcbLockThread ); - doit( FCB, FcbLockCount ); - doit( FCB, FcbNonpaged ); - doit( FCB, ShareAccess ); - doit( FCB, McbEntry ); - doit( FCB, Mcb ); - doit( FCB, ShortNamePrefix ); - doit( FCB, FileNamePrefix ); - doit( FCB, CreationTime ); - doit( FCB, FcbType ); - } - printf("\n"); - { - CCB d; - doit( CCB, NodeTypeCode ); - doit( CCB, NodeByteSize ); - doit( CCB, Flags ); - doit( CCB, Fcb ); - doit( CCB, CurrentDirentOffset ); - doit( CCB, SearchExpression ); - } - printf("\n"); - { - IRP_CONTEXT d; - doit( IRP_CONTEXT, NodeTypeCode ); - doit( IRP_CONTEXT, NodeByteSize ); - doit( IRP_CONTEXT, Irp ); - doit( IRP_CONTEXT, Vcb ); - doit( IRP_CONTEXT, ExceptionStatus ); - doit( IRP_CONTEXT, Flags ); - doit( IRP_CONTEXT, RealDevice ); - doit( IRP_CONTEXT, IoContext ); - doit( IRP_CONTEXT, TeardownFcb ); - doit( IRP_CONTEXT, TopLevel ); - doit( IRP_CONTEXT, MajorFunction ); - doit( IRP_CONTEXT, MinorFunction ); - doit( IRP_CONTEXT, ThreadContext ); - doit( IRP_CONTEXT, WorkQueueItem ); - } - printf("\n"); - { - IRP_CONTEXT_LITE d; - doit( IRP_CONTEXT_LITE, NodeTypeCode ); - doit( IRP_CONTEXT_LITE, NodeByteSize ); - doit( IRP_CONTEXT_LITE, Fcb ); - doit( IRP_CONTEXT_LITE, DelayedCloseLinks ); - doit( IRP_CONTEXT_LITE, UserReference ); - doit( IRP_CONTEXT_LITE, RealDevice ); - } - printf("\n"); - { - CD_IO_CONTEXT d; - doit( CD_IO_CONTEXT, IrpCount ); - doit( CD_IO_CONTEXT, MasterIrp ); - doit( CD_IO_CONTEXT, Status ); - doit( CD_IO_CONTEXT, AllocatedContext ); - doit( CD_IO_CONTEXT, Resource ); - doit( CD_IO_CONTEXT, ResourceThreadId ); - doit( CD_IO_CONTEXT, SyncEvent ); - } - printf("\n"); - { - THREAD_CONTEXT d; - doit( THREAD_CONTEXT, Cdfs ); - doit( THREAD_CONTEXT, SavedTopLevelIrp ); - doit( THREAD_CONTEXT, TopLevelIrpContext ); - } - printf("\n"); - { - PATH_ENUM_CONTEXT d; - doit( PATH_ENUM_CONTEXT, Data ); - doit( PATH_ENUM_CONTEXT, BaseOffset ); - doit( PATH_ENUM_CONTEXT, DataLength ); - doit( PATH_ENUM_CONTEXT, Bcb ); - doit( PATH_ENUM_CONTEXT, DataOffset ); - doit( PATH_ENUM_CONTEXT, AllocatedData ); - doit( PATH_ENUM_CONTEXT, LastDataBlock ); - } - printf("\n"); - { - PATH_ENTRY d; - doit( PATH_ENTRY, Ordinal ); - doit( PATH_ENTRY, PathTableOffset ); - doit( PATH_ENTRY, DiskOffset ); - doit( PATH_ENTRY, PathEntryLength ); - doit( PATH_ENTRY, ParentOrdinal ); - doit( PATH_ENTRY, DirNameLen ); - doit( PATH_ENTRY, DirName ); - doit( PATH_ENTRY, Flags ); - doit( PATH_ENTRY, CdDirName ); - doit( PATH_ENTRY, CdCaseDirName ); - doit( PATH_ENTRY, NameBuffer ); - } - printf("\n"); - { - COMPOUND_PATH_ENTRY d; - doit( COMPOUND_PATH_ENTRY, PathContext ); - doit( COMPOUND_PATH_ENTRY, PathEntry ); - } - printf("\n"); - { - DIRENT_ENUM_CONTEXT d; - doit( DIRENT_ENUM_CONTEXT, Sector ); - doit( DIRENT_ENUM_CONTEXT, BaseOffset ); - doit( DIRENT_ENUM_CONTEXT, DataLength ); - doit( DIRENT_ENUM_CONTEXT, Bcb ); - doit( DIRENT_ENUM_CONTEXT, SectorOffset ); - doit( DIRENT_ENUM_CONTEXT, NextDirentOffset ); - } - printf("\n"); - { - DIRENT d; - doit( DIRENT, DirentOffset ); - doit( DIRENT, DirentLength ); - doit( DIRENT, StartingOffset ); - doit( DIRENT, DataLength ); - doit( DIRENT, CdTime ); - doit( DIRENT, DirentFlags ); - doit( DIRENT, Flags ); - doit( DIRENT, FileUnitSize ); - doit( DIRENT, InterleaveGapSize ); - doit( DIRENT, SystemUseOffset ); - doit( DIRENT, XAAttributes ); - doit( DIRENT, XAFileNumber ); - doit( DIRENT, FileNameLen ); - doit( DIRENT, FileName ); - doit( DIRENT, CdFileName ); - doit( DIRENT, CdCaseFileName ); - doit( DIRENT, ExtentType ); - doit( DIRENT, NameBuffer ); - } - printf("\n"); - { - COMPOUND_DIRENT d; - doit( COMPOUND_DIRENT, DirContext ); - doit( COMPOUND_DIRENT, Dirent ); - } - printf("\n"); - { - FILE_ENUM_CONTEXT d; - doit( FILE_ENUM_CONTEXT, PriorDirent ); - doit( FILE_ENUM_CONTEXT, InitialDirent ); - doit( FILE_ENUM_CONTEXT, CurrentDirent ); - doit( FILE_ENUM_CONTEXT, Flags ); - doit( FILE_ENUM_CONTEXT, FileSize ); - doit( FILE_ENUM_CONTEXT, ShortName ); - doit( FILE_ENUM_CONTEXT, ShortNameBuffer ); - doit( FILE_ENUM_CONTEXT, Dirents ); - } - printf("\n"); - { - RIFF_HEADER d; - doit( RIFF_HEADER, ChunkId ); - doit( RIFF_HEADER, ChunkSize ); - doit( RIFF_HEADER, SignatureCDXA ); - doit( RIFF_HEADER, SignatureFMT ); - doit( RIFF_HEADER, XAChunkSize ); - doit( RIFF_HEADER, OwnerId ); - doit( RIFF_HEADER, Attributes ); - doit( RIFF_HEADER, SignatureXA ); - doit( RIFF_HEADER, FileNumber ); - doit( RIFF_HEADER, Reserved ); - doit( RIFF_HEADER, SignatureData ); - doit( RIFF_HEADER, RawSectors ); - } - printf("\n"); - { - AUDIO_PLAY_HEADER d; - doit( AUDIO_PLAY_HEADER, Chunk ); - doit( AUDIO_PLAY_HEADER, ChunkSize ); - doit( AUDIO_PLAY_HEADER, SignatureCDDA ); - doit( AUDIO_PLAY_HEADER, SignatureFMT ); - doit( AUDIO_PLAY_HEADER, FMTChunkSize ); - doit( AUDIO_PLAY_HEADER, FormatTag ); - doit( AUDIO_PLAY_HEADER, TrackNumber ); - doit( AUDIO_PLAY_HEADER, DiskID ); - doit( AUDIO_PLAY_HEADER, StartingSector ); - doit( AUDIO_PLAY_HEADER, SectorCount ); - doit( AUDIO_PLAY_HEADER, TrackAddress ); - doit( AUDIO_PLAY_HEADER, TrackLength ); - } - printf("\n"); - { - RAW_ISO_VD d; - doit( RAW_ISO_VD, DescType ); - doit( RAW_ISO_VD, StandardId ); - doit( RAW_ISO_VD, Version ); - doit( RAW_ISO_VD, VolumeFlags ); - doit( RAW_ISO_VD, SystemId ); - doit( RAW_ISO_VD, VolumeId ); - doit( RAW_ISO_VD, Reserved ); - doit( RAW_ISO_VD, VolSpaceI ); - doit( RAW_ISO_VD, VolSpaceM ); - doit( RAW_ISO_VD, CharSet ); - doit( RAW_ISO_VD, VolSetSizeI ); - doit( RAW_ISO_VD, VolSetSizeM ); - doit( RAW_ISO_VD, VolSeqNumI ); - doit( RAW_ISO_VD, VolSeqNumM ); - doit( RAW_ISO_VD, LogicalBlkSzI ); - doit( RAW_ISO_VD, LogicalBlkSzM ); - doit( RAW_ISO_VD, PathTableSzI ); - doit( RAW_ISO_VD, PathTableSzM ); - doit( RAW_ISO_VD, PathTabLocI ); - doit( RAW_ISO_VD, PathTabLocM ); - doit( RAW_ISO_VD, RootDe ); - doit( RAW_ISO_VD, VolSetId ); - doit( RAW_ISO_VD, PublId ); - doit( RAW_ISO_VD, PreparerId ); - doit( RAW_ISO_VD, AppId ); - doit( RAW_ISO_VD, Copyright ); - doit( RAW_ISO_VD, Abstract ); - doit( RAW_ISO_VD, Bibliograph ); - doit( RAW_ISO_VD, CreateDate ); - doit( RAW_ISO_VD, ModDate ); - doit( RAW_ISO_VD, ExpireDate ); - doit( RAW_ISO_VD, EffectDate ); - doit( RAW_ISO_VD, FileStructVer ); - doit( RAW_ISO_VD, Reserved3 ); - doit( RAW_ISO_VD, ResApp ); - doit( RAW_ISO_VD, Reserved4 ); - } - printf("\n"); - { - RAW_HSG_VD d; - doit( RAW_HSG_VD, BlkNumI ); - doit( RAW_HSG_VD, BlkNumM ); - doit( RAW_HSG_VD, DescType ); - doit( RAW_HSG_VD, StandardId ); - doit( RAW_HSG_VD, Version ); - doit( RAW_HSG_VD, VolumeFlags ); - doit( RAW_HSG_VD, SystemId ); - doit( RAW_HSG_VD, VolumeId ); - doit( RAW_HSG_VD, Reserved ); - doit( RAW_HSG_VD, VolSpaceI ); - doit( RAW_HSG_VD, VolSpaceM ); - doit( RAW_HSG_VD, CharSet ); - doit( RAW_HSG_VD, VolSetSizeI ); - doit( RAW_HSG_VD, VolSetSizeM ); - doit( RAW_HSG_VD, VolSeqNumI ); - doit( RAW_HSG_VD, VolSeqNumM ); - doit( RAW_HSG_VD, LogicalBlkSzI ); - doit( RAW_HSG_VD, LogicalBlkSzM ); - doit( RAW_HSG_VD, PathTableSzI ); - doit( RAW_HSG_VD, PathTableSzM ); - doit( RAW_HSG_VD, PathTabLocI ); - doit( RAW_HSG_VD, PathTabLocM ); - doit( RAW_HSG_VD, RootDe ); - doit( RAW_HSG_VD, VolSetId ); - doit( RAW_HSG_VD, PublId ); - doit( RAW_HSG_VD, PreparerId ); - doit( RAW_HSG_VD, AppId ); - doit( RAW_HSG_VD, Copyright ); - doit( RAW_HSG_VD, Abstract ); - doit( RAW_HSG_VD, CreateDate ); - doit( RAW_HSG_VD, ModDate ); - doit( RAW_HSG_VD, ExpireDate ); - doit( RAW_HSG_VD, EffectDate ); - doit( RAW_HSG_VD, FileStructVer ); - doit( RAW_HSG_VD, Reserved3 ); - doit( RAW_HSG_VD, ResApp ); - doit( RAW_HSG_VD, Reserved4 ); - } - printf("\n"); - { - RAW_DIRENT d; - doit( RAW_DIRENT, DirLen ); - doit( RAW_DIRENT, XarLen ); - doit( RAW_DIRENT, FileLoc ); - doit( RAW_DIRENT, FileLocMot ); - doit( RAW_DIRENT, DataLen ); - doit( RAW_DIRENT, DataLenMot ); - doit( RAW_DIRENT, RecordTime ); - doit( RAW_DIRENT, FlagsHSG ); - doit( RAW_DIRENT, FlagsISO ); - doit( RAW_DIRENT, IntLeaveSize ); - doit( RAW_DIRENT, IntLeaveSkip ); - doit( RAW_DIRENT, Vssn ); - doit( RAW_DIRENT, VssnMot ); - doit( RAW_DIRENT, FileIdLen ); - doit( RAW_DIRENT, FileId ); - } - printf("\n"); - { - RAW_PATH_ISO d; - doit( RAW_PATH_ISO, DirIdLen ); - doit( RAW_PATH_ISO, XarLen ); - doit( RAW_PATH_ISO, DirLoc ); - doit( RAW_PATH_ISO, ParentNum ); - doit( RAW_PATH_ISO, DirId ); - } - printf("\n"); - { - RAW_PATH_HSG d; - doit( RAW_PATH_HSG, DirLoc ); - doit( RAW_PATH_HSG, XarLen ); - doit( RAW_PATH_HSG, DirIdLen ); - doit( RAW_PATH_HSG, ParentNum ); - doit( RAW_PATH_HSG, DirId ); - } - printf("\n"); - { - SYSTEM_USE_XA d; - doit( SYSTEM_USE_XA, OwnerId ); - doit( SYSTEM_USE_XA, Attributes ); - doit( SYSTEM_USE_XA, Signature ); - doit( SYSTEM_USE_XA, FileNumber ); - doit( SYSTEM_USE_XA, Reserved ); - } -} - diff --git a/reactos/drivers/filesystems/cdfs_new/fileinfo.c b/reactos/drivers/filesystems/cdfs_new/fileinfo.c deleted file mode 100755 index c357d3c9969..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/fileinfo.c +++ /dev/null @@ -1,1504 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - FileInfo.c - -Abstract: - - This module implements the File Information routines for Cdfs called by - the Fsd/Fsp dispatch drivers. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_FILEINFO) - -// -// Local support routines -// - -VOID -CdQueryBasicInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_BASIC_INFORMATION Buffer, - IN OUT PULONG Length - ); - -VOID -CdQueryStandardInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_STANDARD_INFORMATION Buffer, - IN OUT PULONG Length - ); - -VOID -CdQueryInternalInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_INTERNAL_INFORMATION Buffer, - IN OUT PULONG Length - ); - -VOID -CdQueryEaInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_EA_INFORMATION Buffer, - IN OUT PULONG Length - ); - -VOID -CdQueryPositionInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN OUT PFILE_POSITION_INFORMATION Buffer, - IN OUT PULONG Length - ); - -NTSTATUS -CdQueryNameInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN OUT PFILE_NAME_INFORMATION Buffer, - IN OUT PULONG Length - ); - -NTSTATUS -CdQueryAlternateNameInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PCCB Ccb, - IN OUT PFILE_NAME_INFORMATION Buffer, - IN OUT PULONG Length - ); - -VOID -CdQueryNetworkInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer, - IN OUT PULONG Length - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCommonQueryInfo) -#pragma alloc_text(PAGE, CdCommonSetInfo) -#pragma alloc_text(PAGE, CdFastQueryBasicInfo) -#pragma alloc_text(PAGE, CdFastQueryStdInfo) -#pragma alloc_text(PAGE, CdFastQueryNetworkInfo) -#pragma alloc_text(PAGE, CdQueryAlternateNameInfo) -#pragma alloc_text(PAGE, CdQueryBasicInfo) -#pragma alloc_text(PAGE, CdQueryEaInfo) -#pragma alloc_text(PAGE, CdQueryInternalInfo) -#pragma alloc_text(PAGE, CdQueryNameInfo) -#pragma alloc_text(PAGE, CdQueryNetworkInfo) -#pragma alloc_text(PAGE, CdQueryPositionInfo) -#pragma alloc_text(PAGE, CdQueryStandardInfo) -#endif - - -NTSTATUS -CdCommonQueryInfo ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the common routine for query file information called by both the - fsd and fsp threads. - -Arguments: - - Irp - Supplies the Irp to process. - -Return Value: - - NTSTATUS - The return status for this operation. - ---*/ - -{ - NTSTATUS Status = STATUS_SUCCESS; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - ULONG Length; - FILE_INFORMATION_CLASS FileInformationClass; - PFILE_ALL_INFORMATION Buffer; - - TYPE_OF_OPEN TypeOfOpen; - PFCB Fcb; - PCCB Ccb; - - BOOLEAN ReleaseFcb = FALSE; - - PAGED_CODE(); - - // - // Reference our input parameters to make things easier - // - - Length = IrpSp->Parameters.QueryFile.Length; - FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass; - Buffer = Irp->AssociatedIrp.SystemBuffer; - - // - // Decode the file object - // - - TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ); - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // We only support query on file and directory handles. - // - - switch (TypeOfOpen) { - - case UserDirectoryOpen : - case UserFileOpen : - - // - // Acquire shared access to this file. NOTE that this could be - // a recursive acquire, if we already preacquired in - // CdAcquireForCreateSection(). - // - - CdAcquireFileShared( IrpContext, Fcb ); - ReleaseFcb = TRUE; - - // - // Make sure we have the correct sizes for a directory. - // - - if (!FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED )) { - - ASSERT( TypeOfOpen == UserDirectoryOpen ); - CdCreateInternalStream( IrpContext, Fcb->Vcb, Fcb ); - } - - // - // Make sure the Fcb is in a usable condition. This will raise - // an error condition if the volume is unusable - // - - CdVerifyFcbOperation( IrpContext, Fcb ); - - // - // Based on the information class we'll do different - // actions. Each of hte procedures that we're calling fills - // up the output buffer, if possible. They will raise the - // status STATUS_BUFFER_OVERFLOW for an insufficient buffer. - // This is considered a somewhat unusual case and is handled - // more cleanly with the exception mechanism rather than - // testing a return status value for each call. - // - - switch (FileInformationClass) { - - case FileAllInformation: - - // - // We don't allow this operation on a file opened by file Id. - // - - if (FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) { - - Status = STATUS_INVALID_PARAMETER; - break; - } - - // - // In this case go ahead and call the individual routines to - // fill in the buffer. Only the name routine will - // pointer to the output buffer and then call the - // individual routines to fill in the buffer. - // - - Length -= (sizeof( FILE_ACCESS_INFORMATION ) + - sizeof( FILE_MODE_INFORMATION ) + - sizeof( FILE_ALIGNMENT_INFORMATION )); - - CdQueryBasicInfo( IrpContext, Fcb, &Buffer->BasicInformation, &Length ); - CdQueryStandardInfo( IrpContext, Fcb, &Buffer->StandardInformation, &Length ); - CdQueryInternalInfo( IrpContext, Fcb, &Buffer->InternalInformation, &Length ); - CdQueryEaInfo( IrpContext, Fcb, &Buffer->EaInformation, &Length ); - CdQueryPositionInfo( IrpContext, IrpSp->FileObject, &Buffer->PositionInformation, &Length ); - Status = CdQueryNameInfo( IrpContext, IrpSp->FileObject, &Buffer->NameInformation, &Length ); - - break; - - case FileBasicInformation: - - CdQueryBasicInfo( IrpContext, Fcb, (PFILE_BASIC_INFORMATION) Buffer, &Length ); - break; - - case FileStandardInformation: - - CdQueryStandardInfo( IrpContext, Fcb, (PFILE_STANDARD_INFORMATION) Buffer, &Length ); - break; - - case FileInternalInformation: - - CdQueryInternalInfo( IrpContext, Fcb, (PFILE_INTERNAL_INFORMATION) Buffer, &Length ); - break; - - case FileEaInformation: - - CdQueryEaInfo( IrpContext, Fcb, (PFILE_EA_INFORMATION) Buffer, &Length ); - break; - - case FilePositionInformation: - - CdQueryPositionInfo( IrpContext, IrpSp->FileObject, (PFILE_POSITION_INFORMATION) Buffer, &Length ); - break; - - case FileNameInformation: - - // - // We don't allow this operation on a file opened by file Id. - // - - if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) { - - Status = CdQueryNameInfo( IrpContext, IrpSp->FileObject, (PFILE_NAME_INFORMATION) Buffer, &Length ); - - } else { - - Status = STATUS_INVALID_PARAMETER; - } - - break; - - case FileAlternateNameInformation: - - if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) { - - Status = CdQueryAlternateNameInfo( IrpContext, Fcb, Ccb, (PFILE_NAME_INFORMATION) Buffer, &Length ); - - } else { - - Status = STATUS_INVALID_PARAMETER; - } - - break; - - case FileNetworkOpenInformation: - - CdQueryNetworkInfo( IrpContext, Fcb, (PFILE_NETWORK_OPEN_INFORMATION) Buffer, &Length ); - break; - - default : - - Status = STATUS_INVALID_PARAMETER; - } - - break; - - default : - - Status = STATUS_INVALID_PARAMETER; - } - - // - // Set the information field to the number of bytes actually filled in - // and then complete the request - // - - Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length; - - } finally { - - // - // Release the file. - // - - if (ReleaseFcb) { - - CdReleaseFile( IrpContext, Fcb ); - } - } - - // - // Complete the request if we didn't raise. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - - return Status; -} - - -NTSTATUS -CdCommonSetInfo ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the common routine for set file information called by both the - fsd and fsp threads. We only support operations which set the file position. - -Arguments: - - Irp - Supplies the Irp to process. - -Return Value: - - NTSTATUS - The return status for this operation. - ---*/ - -{ - NTSTATUS Status = STATUS_INVALID_PARAMETER; - - TYPE_OF_OPEN TypeOfOpen; - PFCB Fcb; - PCCB Ccb; - - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PFILE_POSITION_INFORMATION Buffer; - - PAGED_CODE(); - - // - // Decode the file object - // - - TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ); - - // - // We only support a SetPositionInformation on a user file. - // - - if ((TypeOfOpen != UserFileOpen) || - (IrpSp->Parameters.QueryFile.FileInformationClass != FilePositionInformation)) { - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; - } - - // - // Acquire shared access to this file. - // - - CdAcquireFileShared( IrpContext, Fcb ); - - try { - - // - // Make sure the Fcb is in a usable condition. This - // will raise an error condition if the fcb is unusable - // - - CdVerifyFcbOperation( IrpContext, Fcb ); - - Buffer = Irp->AssociatedIrp.SystemBuffer; - - // - // Check if the file does not use intermediate buffering. If it - // does not use intermediate buffering then the new position we're - // supplied must be aligned properly for the device - // - - if (FlagOn( IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING ) && - ((Buffer->CurrentByteOffset.LowPart & Fcb->Vcb->BlockMask) != 0)) { - - try_return( NOTHING ); - } - - // - // The input parameter is fine so set the current byte offset and - // complete the request - // - - // - // Lock the Fcb to provide synchronization. - // - - CdLockFcb( IrpContext, Fcb ); - IrpSp->FileObject->CurrentByteOffset = Buffer->CurrentByteOffset; - CdUnlockFcb( IrpContext, Fcb ); - - Status = STATUS_SUCCESS; - - try_exit: NOTHING; - } finally { - - CdReleaseFile( IrpContext, Fcb ); - } - - // - // Complete the request if there was no raise. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; -} - - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastQueryBasicInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, - IN OUT PFILE_BASIC_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ) - -/*++ - -Routine Description: - - This routine is for the fast query call for basic file information. - -Arguments: - - FileObject - Supplies the file object used in this operation - - Wait - Indicates if we are allowed to wait for the information - - Buffer - Supplies the output buffer to receive the basic information - - IoStatus - Receives the final status of the operation - -Return Value: - - BOOLEAN - TRUE if the operation succeeded and FALSE if the caller - needs to take the long route. - ---*/ - -{ - BOOLEAN Result = FALSE; - TYPE_OF_OPEN TypeOfOpen; - - PFCB Fcb; - - PAGED_CODE(); - - ASSERT_FILE_OBJECT( FileObject ); - - FsRtlEnterFileSystem(); - - // - // Decode the file object to find the type of open and the data - // structures. - // - - TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb ); - - // - // We only support this request on user file or directory objects. - // - - if ((TypeOfOpen != UserFileOpen) && - ((TypeOfOpen != UserDirectoryOpen) || !FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED))) { - - FsRtlExitFileSystem(); - return FALSE; - } - - // - // Acquire the file shared to access the Fcb. - // - - if (!ExAcquireResourceSharedLite( Fcb->Resource, Wait )) { - - FsRtlExitFileSystem(); - return FALSE; - } - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Only deal with 'good' Fcb's. - // - - if (CdVerifyFcbOperation( NULL, Fcb )) { - - // - // Fill in the input buffer from the Fcb fields. - // - - Buffer->CreationTime.QuadPart = - Buffer->LastWriteTime.QuadPart = - Buffer->ChangeTime.QuadPart = Fcb->CreationTime; - - Buffer->LastAccessTime.QuadPart = 0; - - Buffer->FileAttributes = Fcb->FileAttributes; - - // - // Update the IoStatus block with the size of this data. - // - - IoStatus->Status = STATUS_SUCCESS; - IoStatus->Information = sizeof( FILE_BASIC_INFORMATION ); - - Result = TRUE; - } - - } finally { - - ExReleaseResourceLite( Fcb->Resource ); - - FsRtlExitFileSystem(); - } - - return Result; -} - - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastQueryStdInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, - IN OUT PFILE_STANDARD_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ) - -/*++ - -Routine Description: - - This routine is for the fast query call for standard file information. - -Arguments: - - FileObject - Supplies the file object used in this operation - - Wait - Indicates if we are allowed to wait for the information - - Buffer - Supplies the output buffer to receive the basic information - - IoStatus - Receives the final status of the operation - -Return Value: - - BOOLEAN - TRUE if the operation succeeded and FALSE if the caller - needs to take the long route. - ---*/ - -{ - BOOLEAN Result = FALSE; - TYPE_OF_OPEN TypeOfOpen; - - PFCB Fcb; - - PAGED_CODE(); - - ASSERT_FILE_OBJECT( FileObject ); - - FsRtlEnterFileSystem(); - - // - // Decode the file object to find the type of open and the data - // structures. - // - - TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb ); - - // - // We only support this request on initialized user file or directory objects. - // - - if ((TypeOfOpen != UserFileOpen) && - ((TypeOfOpen != UserDirectoryOpen) || !FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED ))) { - - FsRtlExitFileSystem(); - return FALSE; - } - - // - // Acquire the file shared to access the Fcb. - // - - if (!ExAcquireResourceSharedLite( Fcb->Resource, Wait )) { - - FsRtlExitFileSystem(); - return FALSE; - } - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Only deal with 'good' Fcb's. - // - - if (CdVerifyFcbOperation( NULL, Fcb )) { - - // - // Check whether this is a directory. - // - - if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) { - - Buffer->AllocationSize.QuadPart = - Buffer->EndOfFile.QuadPart = 0; - - Buffer->Directory = TRUE; - - } else { - - Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart; - Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart; - - Buffer->Directory = FALSE; - } - - Buffer->NumberOfLinks = 1; - Buffer->DeletePending = FALSE; - - // - // Update the IoStatus block with the size of this data. - // - - IoStatus->Status = STATUS_SUCCESS; - IoStatus->Information = sizeof( FILE_STANDARD_INFORMATION ); - - Result = TRUE; - } - - } finally { - - ExReleaseResourceLite( Fcb->Resource ); - - FsRtlExitFileSystem(); - } - - return Result; -} - - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastQueryNetworkInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, - OUT PFILE_NETWORK_OPEN_INFORMATION Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ) - -/*++ - -Routine Description: - - This routine is for the fast query call for network file information. - -Arguments: - - FileObject - Supplies the file object used in this operation - - Wait - Indicates if we are allowed to wait for the information - - Buffer - Supplies the output buffer to receive the basic information - - IoStatus - Receives the final status of the operation - -Return Value: - - BOOLEAN - TRUE if the operation succeeded and FALSE if the caller - needs to take the long route. - ---*/ - -{ - BOOLEAN Result = FALSE; - TYPE_OF_OPEN TypeOfOpen; - - PFCB Fcb; - - PAGED_CODE(); - - ASSERT_FILE_OBJECT( FileObject ); - - FsRtlEnterFileSystem(); - - // - // Decode the file object to find the type of open and the data - // structures. - // - - TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb ); - - // - // We only support this request on user file or directory objects. - // - - if ((TypeOfOpen != UserFileOpen) && - ((TypeOfOpen != UserDirectoryOpen) || !FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED))) { - - FsRtlExitFileSystem(); - return FALSE; - } - - // - // Acquire the file shared to access the Fcb. - // - - if (!ExAcquireResourceSharedLite( Fcb->Resource, Wait )) { - - FsRtlExitFileSystem(); - return FALSE; - } - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Only deal with 'good' Fcb's. - // - - if (CdVerifyFcbOperation( NULL, Fcb )) { - - // - // Fill in the input buffer from the Fcb fields. - // - - Buffer->CreationTime.QuadPart = - Buffer->LastWriteTime.QuadPart = - Buffer->ChangeTime.QuadPart = Fcb->CreationTime; - - Buffer->LastAccessTime.QuadPart = 0; - - Buffer->FileAttributes = Fcb->FileAttributes; - - // - // Check whether this is a directory. - // - - if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) { - - Buffer->AllocationSize.QuadPart = - Buffer->EndOfFile.QuadPart = 0; - - } else { - - Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart; - Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart; - } - - // - // Update the IoStatus block with the size of this data. - // - - IoStatus->Status = STATUS_SUCCESS; - IoStatus->Information = sizeof( FILE_NETWORK_OPEN_INFORMATION ); - - Result = TRUE; - } - - } finally { - - ExReleaseResourceLite( Fcb->Resource ); - - FsRtlExitFileSystem(); - } - - return Result; -} - - -// -// Local support routine -// - -VOID -CdQueryBasicInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_BASIC_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - - Description: - - This routine performs the query basic information function for Cdfs - -Arguments: - - Fcb - Supplies the Fcb being queried, it has been verified - - Buffer - Supplies a pointer to the buffer where the information is to - be returned - - Length - Supplies the length of the buffer in bytes, and receives the - remaining bytes free in the buffer upon return. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // - // We only support creation, last modify and last write times on Cdfs. - // - - Buffer->LastWriteTime.QuadPart = - Buffer->CreationTime.QuadPart = - Buffer->ChangeTime.QuadPart = Fcb->CreationTime; - - Buffer->LastAccessTime.QuadPart = 0; - - Buffer->FileAttributes = Fcb->FileAttributes; - - // - // Update the length and status output variables - // - - *Length -= sizeof( FILE_BASIC_INFORMATION ); - - return; -} - - -// -// Local support routine -// - -VOID -CdQueryStandardInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_STANDARD_INFORMATION Buffer, - IN OUT PULONG Length - ) -/*++ - -Routine Description: - - This routine performs the query standard information function for cdfs. - -Arguments: - - Fcb - Supplies the Fcb being queried, it has been verified - - Buffer - Supplies a pointer to the buffer where the information is to - be returned - - Length - Supplies the length of the buffer in bytes, and receives the - remaining bytes free in the buffer upon return. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // - // There is only one link and delete is never pending on a Cdrom file. - // - - Buffer->NumberOfLinks = 1; - Buffer->DeletePending = FALSE; - - // - // We get the sizes from the header. Return a size of zero - // for all directories. - // - - if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) { - - Buffer->AllocationSize.QuadPart = - Buffer->EndOfFile.QuadPart = 0; - - Buffer->Directory = TRUE; - - } else { - - Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart; - Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart; - - Buffer->Directory = FALSE; - } - - // - // Update the length and status output variables - // - - *Length -= sizeof( FILE_STANDARD_INFORMATION ); - - return; -} - - -// -// Local support routine -// - -VOID -CdQueryInternalInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_INTERNAL_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - -Routine Description: - - This routine performs the query internal information function for cdfs. - -Arguments: - - Fcb - Supplies the Fcb being queried, it has been verified - - Buffer - Supplies a pointer to the buffer where the information is to - be returned - - Length - Supplies the length of the buffer in bytes, and receives the - remaining bytes free in the buffer upon return. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // - // Index number is the file Id number in the Fcb. - // - - Buffer->IndexNumber = Fcb->FileId; - *Length -= sizeof( FILE_INTERNAL_INFORMATION ); - - return; -} - - -// -// Local support routine -// - -VOID -CdQueryEaInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_EA_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - -Routine Description: - - This routine performs the query Ea information function for cdfs. - -Arguments: - - Fcb - Supplies the Fcb being queried, it has been verified - - Buffer - Supplies a pointer to the buffer where the information is to - be returned - - Length - Supplies the length of the buffer in bytes, and receives the - remaining bytes free in the buffer upon return. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // - // No Ea's on Cdfs volumes. - // - - Buffer->EaSize = 0; - *Length -= sizeof( FILE_EA_INFORMATION ); - - return; -} - - -// -// Local support routine -// - -VOID -CdQueryPositionInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN OUT PFILE_POSITION_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - -Routine Description: - - This routine performs the query position information function for cdfs. - -Arguments: - - FileObject - Supplies the File object being queried - - Buffer - Supplies a pointer to the buffer where the information is to - be returned - - Length - Supplies the length of the buffer in bytes, and receives the - remaining bytes free in the buffer upon return. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // - // Get the current position found in the file object. - // - - Buffer->CurrentByteOffset = FileObject->CurrentByteOffset; - - // - // Update the length and status output variables - // - - *Length -= sizeof( FILE_POSITION_INFORMATION ); - - return; -} - - -// -// Local support routine -// - -NTSTATUS -CdQueryNameInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN OUT PFILE_NAME_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - -Routine Description: - - This routine performs the query name information function for cdfs. - -Arguments: - - FileObject - Supplies the file object containing the name. - - Buffer - Supplies a pointer to the buffer where the information is to - be returned - - Length - Supplies the length of the buffer in bytes, and receives the - remaining bytes free in the buffer upon return. - -Return Value: - - NTSTATUS - STATUS_BUFFER_OVERFLOW if the entire name can't be copied. - ---*/ - -{ - NTSTATUS Status = STATUS_SUCCESS; - ULONG LengthToCopy; - - PAGED_CODE(); - - ASSERT(*Length >= sizeof(ULONG)); - - // - // Simply copy the name in the file object to the user's buffer. - // - - // - // Place the size of the filename in the user's buffer and reduce the remaining - // size to match. - // - - Buffer->FileNameLength = LengthToCopy = FileObject->FileName.Length; - *Length -= sizeof(ULONG); - - if (LengthToCopy > *Length) { - - LengthToCopy = *Length; - Status = STATUS_BUFFER_OVERFLOW; - } - - RtlCopyMemory( Buffer->FileName, FileObject->FileName.Buffer, LengthToCopy ); - - // - // Reduce the available bytes by the amount stored into this buffer. In the overflow - // case, this simply drops to zero. The returned filenamelength will indicate to the - // caller how much space is required. - // - - *Length -= LengthToCopy; - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdQueryAlternateNameInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PCCB Ccb, - IN OUT PFILE_NAME_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - -Routine Description: - - This routine performs the query alternate name information function. - We lookup the dirent for this file and then check if there is a - short name. - -Arguments: - - Fcb - Supplies the Fcb being queried, it has been verified. - - Ccb - Ccb for this open handle. - - Buffer - Supplies a pointer to the buffer where the information is to - be returned. - - Length - Supplies the length of the buffer in bytes, and receives the - remaining bytes free in the buffer upon return. - -Return Value: - - NTSTATUS - STATUS_SUCCESS if the whole name would fit into the user buffer, - STATUS_OBJECT_NAME_NOT_FOUND if we can't return the name, - STATUS_BUFFER_OVERFLOW otherwise. - ---*/ - -{ - NTSTATUS Status = STATUS_SUCCESS; - - DIRENT_ENUM_CONTEXT DirContext; - DIRENT Dirent; - - PUNICODE_STRING NameToUse; - ULONG DirentOffset; - - COMPOUND_PATH_ENTRY CompoundPathEntry; - FILE_ENUM_CONTEXT FileContext; - - PFCB ParentFcb; - BOOLEAN ReleaseParentFcb = FALSE; - - BOOLEAN CleanupFileLookup = FALSE; - BOOLEAN CleanupDirectoryLookup = FALSE; - - WCHAR ShortNameBuffer[ BYTE_COUNT_8_DOT_3 / 2 ]; - USHORT ShortNameLength; - - PAGED_CODE(); - - // - // Initialize the buffer length to zero. - // - - Buffer->FileNameLength = 0; - - // - // If this is the root or this file was opened using a version number then - // there is no short name. - // - - if ((Fcb == Fcb->Vcb->RootIndexFcb) || - FlagOn( Ccb->Flags, CCB_FLAG_OPEN_WITH_VERSION)) { - - return STATUS_OBJECT_NAME_NOT_FOUND; - } - - // - // Use a try-finally to cleanup the structures. - // - - try { - - ParentFcb = Fcb->ParentFcb; - CdAcquireFileShared( IrpContext, ParentFcb ); - ReleaseParentFcb = TRUE; - - // - // Do an unsafe test to see if we need to create a file object. - // - - if (ParentFcb->FileObject == NULL) { - - CdCreateInternalStream( IrpContext, ParentFcb->Vcb, ParentFcb ); - } - - if (CdFidIsDirectory( Fcb->FileId)) { - - // - // Fcb is for a directory, so we need to dig the dirent from the parent. In - // order to do this we need to get the name of the directory from its pathtable - // entry and then search in the parent for a matching dirent. - // - // This could be optimized somewhat. - // - - CdInitializeCompoundPathEntry( IrpContext, &CompoundPathEntry ); - CdInitializeFileContext( IrpContext, &FileContext ); - - CleanupDirectoryLookup = TRUE; - - CdLookupPathEntry( IrpContext, - CdQueryFidPathTableOffset( Fcb->FileId ), - Fcb->Ordinal, - FALSE, - &CompoundPathEntry ); - - CdUpdatePathEntryName( IrpContext, &CompoundPathEntry.PathEntry, TRUE ); - - if (!CdFindDirectory( IrpContext, - ParentFcb, - &CompoundPathEntry.PathEntry.CdCaseDirName, - TRUE, - &FileContext )) { - - // - // If we failed to find the child directory by name in the parent - // something is quite wrong with this disc. - // - - CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); - } - - NameToUse = &FileContext.InitialDirent->Dirent.CdCaseFileName.FileName; - DirentOffset = FileContext.InitialDirent->Dirent.DirentOffset; - - } else { - - // - // Initialize the search dirent structures. - // - - CdInitializeDirContext( IrpContext, &DirContext ); - CdInitializeDirent( IrpContext, &Dirent ); - - CleanupFileLookup = TRUE; - - CdLookupDirent( IrpContext, - ParentFcb, - CdQueryFidDirentOffset( Fcb->FileId ), - &DirContext ); - - CdUpdateDirentFromRawDirent( IrpContext, - ParentFcb, - &DirContext, - &Dirent ); - - // - // Now update the dirent name. - // - - CdUpdateDirentName( IrpContext, &Dirent, TRUE ); - - NameToUse = &Dirent.CdCaseFileName.FileName; - DirentOffset = Dirent.DirentOffset; - } - - // - // If the name is 8.3 then fail this request. - // - - if (CdIs8dot3Name( IrpContext, - *NameToUse )) { - - - try_return( Status = STATUS_OBJECT_NAME_NOT_FOUND ); - } - - CdGenerate8dot3Name( IrpContext, - NameToUse, - DirentOffset, - ShortNameBuffer, - &ShortNameLength ); - - // - // We now have the short name. We have left it in Unicode form so copy it directly. - // - - Buffer->FileNameLength = ShortNameLength; - - if (Buffer->FileNameLength + sizeof( ULONG ) > *Length) { - - Buffer->FileNameLength = *Length - sizeof( ULONG ); - Status = STATUS_BUFFER_OVERFLOW; - } - - RtlCopyMemory( Buffer->FileName, ShortNameBuffer, Buffer->FileNameLength ); - - try_exit: NOTHING; - } finally { - - if (CleanupFileLookup) { - - CdCleanupDirContext( IrpContext, &DirContext ); - CdCleanupDirent( IrpContext, &Dirent ); - - } else if (CleanupDirectoryLookup) { - - CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry ); - CdCleanupFileContext( IrpContext, &FileContext ); - } - - if (ReleaseParentFcb) { - - CdReleaseFile( IrpContext, ParentFcb ); - } - } - - // - // Reduce the available bytes by the amount stored into this buffer. - // - - if (Status != STATUS_OBJECT_NAME_NOT_FOUND) { - - *Length -= sizeof( ULONG ) + Buffer->FileNameLength; - } - - return Status; -} - - -// -// Local support routine -// - -VOID -CdQueryNetworkInfo ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - - Description: - - This routine performs the query network open information function for Cdfs - -Arguments: - - Fcb - Supplies the Fcb being queried, it has been verified - - Buffer - Supplies a pointer to the buffer where the information is to - be returned - - Length - Supplies the length of the buffer in bytes, and receives the - remaining bytes free in the buffer upon return. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // - // We only support creation, last modify and last write times on Cdfs. - // - - Buffer->LastWriteTime.QuadPart = - Buffer->CreationTime.QuadPart = - Buffer->ChangeTime.QuadPart = Fcb->CreationTime; - - Buffer->LastAccessTime.QuadPart = 0; - - Buffer->FileAttributes = Fcb->FileAttributes; - - // - // We get the sizes from the header. Return a size of zero - // for all directories. - // - - if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) { - - Buffer->AllocationSize.QuadPart = - Buffer->EndOfFile.QuadPart = 0; - - } else { - - Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart; - Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart; - } - - // - // Update the length and status output variables - // - - *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION ); - - return; -} - diff --git a/reactos/drivers/filesystems/cdfs_new/filobsup.c b/reactos/drivers/filesystems/cdfs_new/filobsup.c deleted file mode 100755 index 909d1a89a27..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/filobsup.c +++ /dev/null @@ -1,234 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - FilObSup.c - -Abstract: - - This module implements the Cdfs File object support routines. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_FILOBSUP) - -// -// Local constants. -// - -#define TYPE_OF_OPEN_MASK (0x00000007) - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdDecodeFileObject) -#pragma alloc_text(PAGE, CdFastDecodeFileObject) -#pragma alloc_text(PAGE, CdSetFileObject) -#endif - - -VOID -CdSetFileObject ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - IN TYPE_OF_OPEN TypeOfOpen, - IN PFCB Fcb OPTIONAL, - IN PCCB Ccb OPTIONAL - ) - -/*++ - -Routine Description: - - This routine will initialize the FileObject context fields based on the - input type and data structures. - -Arguments: - - FileObject - Supplies the file object pointer being initialized. - - TypeOfOpen - Sets the type of open. - - Fcb - Fcb for this file object. Ignored for UnopenedFileObject. - - Ccb - Ccb for the handle corresponding to this file object. Will not - be present for stream file objects. - -Return Value: - - None. - ---*/ - -{ - PAGED_CODE(); - - // - // We only have values 0 to 7 available so make sure we didn't - // inadvertantly add a new type. - // - - ASSERTMSG( "FileObject types exceed available bits\n", BeyondValidType <= 8 ); - - // - // Setting a file object to type UnopenedFileObject means just - // clearing all of the context fields. All the other input - // - - if (TypeOfOpen == UnopenedFileObject) { - - FileObject->FsContext = - FileObject->FsContext2 = NULL; - - return; - } - - // - // Check that the 3 low-order bits of the Ccb are clear. - // - - ASSERTMSG( "Ccb is not quad-aligned\n", !FlagOn( ((ULONG_PTR) Ccb), TYPE_OF_OPEN_MASK )); - - // - // We will or the type of open into the low order bits of FsContext2 - // along with the Ccb value. - // The Fcb is stored into the FsContext field. - // - - FileObject->FsContext = Fcb; - FileObject->FsContext2 = Ccb; - - SetFlag( (*(PULONG_PTR)&FileObject->FsContext2), TypeOfOpen ); /* ReactOS Change: GCC "invalid lvalue in assignment" */ - - // - // Set the Vpb field in the file object. - // - - FileObject->Vpb = Fcb->Vcb->Vpb; - - return; -} - - - -TYPE_OF_OPEN -CdDecodeFileObject ( - IN PIRP_CONTEXT IrpContext, - IN PFILE_OBJECT FileObject, - OUT PFCB *Fcb, - OUT PCCB *Ccb - ) - -/*++ - -Routine Description: - - This routine takes a file object and extracts the Fcb and Ccb (possibly NULL) - and returns the type of open. - -Arguments: - - FileObject - Supplies the file object pointer being initialized. - - Fcb - Address to store the Fcb contained in the file object. - - Ccb - Address to store the Ccb contained in the file object. - -Return Value: - - TYPE_OF_OPEN - Indicates the type of file object. - ---*/ - -{ - TYPE_OF_OPEN TypeOfOpen; - - PAGED_CODE(); - - // - // If this is an unopened file object then return NULL for the - // Fcb/Ccb. Don't trust any other values in the file object. - // - - TypeOfOpen = (TYPE_OF_OPEN) FlagOn( (ULONG_PTR) FileObject->FsContext2, - TYPE_OF_OPEN_MASK ); - - if (TypeOfOpen == UnopenedFileObject) { - - *Fcb = NULL; - *Ccb = NULL; - - } else { - - // - // The Fcb is pointed to by the FsContext field. The Ccb is in - // FsContext2 (after clearing the low three bits). The low three - // bits are the file object type. - // - - *Fcb = FileObject->FsContext; - *Ccb = FileObject->FsContext2; - - ClearFlag( (*(PULONG_PTR)Ccb), TYPE_OF_OPEN_MASK ); /* ReactOS Change: GCC "invalid lvalue in assignment" */ - } - - // - // Now return the type of open. - // - - return TypeOfOpen; -} - - -TYPE_OF_OPEN -CdFastDecodeFileObject ( - IN PFILE_OBJECT FileObject, - OUT PFCB *Fcb - ) - -/*++ - -Routine Description: - - This procedure takes a pointer to a file object, that has already been - opened by Cdfs and does a quick decode operation. It will only return - a non null value if the file object is a user file open - -Arguments: - - FileObject - Supplies the file object pointer being interrogated - - Fcb - Address to store Fcb if this is a user file object. NULL - otherwise. - -Return Value: - - TYPE_OF_OPEN - type of open of this file object. - ---*/ - -{ - PAGED_CODE(); - - ASSERT_FILE_OBJECT( FileObject ); - - // - // The Fcb is in the FsContext field. The type of open is in the low - // bits of the Ccb. - // - - *Fcb = FileObject->FsContext; - - return (TYPE_OF_OPEN) - FlagOn( (ULONG_PTR) FileObject->FsContext2, TYPE_OF_OPEN_MASK ); -} - - - diff --git a/reactos/drivers/filesystems/cdfs_new/fsctrl.c b/reactos/drivers/filesystems/cdfs_new/fsctrl.c deleted file mode 100755 index f2a9db1dfa1..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/fsctrl.c +++ /dev/null @@ -1,3167 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - FsCtrl.c - -Abstract: - - This module implements the File System Control routines for Cdfs called - by the Fsd/Fsp dispatch drivers. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_FSCTRL) - -// -// Local constants -// - -BOOLEAN CdDisable = FALSE; -BOOLEAN CdNoJoliet = FALSE; - -// -// Local support routines -// - -NTSTATUS -CdUserFsctl ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -VOID -CdReMountOldVcb( - IN PIRP_CONTEXT IrpContext, - IN PVCB OldVcb, - IN PVCB NewVcb, - IN PDEVICE_OBJECT DeviceObjectWeTalkTo - ); - -NTSTATUS -CdMountVolume ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdVerifyVolume ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdOplockRequest ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdLockVolume ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdUnlockVolume ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdDismountVolume ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS /* ReactOS Change: Function did not have a type??? */ -CdIsVolumeDirty ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdIsVolumeMounted ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdIsPathnameValid ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -NTSTATUS -CdInvalidateVolumes ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -VOID -CdScanForDismountedVcb ( - IN PIRP_CONTEXT IrpContext - ); - -BOOLEAN -CdFindPrimaryVd ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PCHAR RawIsoVd, - IN ULONG BlockFactor, - IN BOOLEAN ReturnOnError, - IN BOOLEAN VerifyVolume - ); - -BOOLEAN -CdIsRemount ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - OUT PVCB *OldVcb - ); - -VOID -CdFindActiveVolDescriptor ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN OUT PCHAR RawIsoVd, - IN BOOLEAN VerifyVolume - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCommonFsControl) -#pragma alloc_text(PAGE, CdDismountVolume) -#pragma alloc_text(PAGE, CdFindActiveVolDescriptor) -#pragma alloc_text(PAGE, CdFindPrimaryVd) -#pragma alloc_text(PAGE, CdIsPathnameValid) -#pragma alloc_text(PAGE, CdIsRemount) -#pragma alloc_text(PAGE, CdIsVolumeDirty) -#pragma alloc_text(PAGE, CdIsVolumeMounted) -#pragma alloc_text(PAGE, CdLockVolume) -#pragma alloc_text(PAGE, CdMountVolume) -#pragma alloc_text(PAGE, CdOplockRequest) -#pragma alloc_text(PAGE, CdScanForDismountedVcb) -#pragma alloc_text(PAGE, CdUnlockVolume) -#pragma alloc_text(PAGE, CdUserFsctl) -#pragma alloc_text(PAGE, CdVerifyVolume) -#endif - - -// -// Local support routine -// - -NTSTATUS -CdLockVolumeInternal ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_OBJECT FileObject OPTIONAL - ) - -/*++ - -Routine Description: - - This routine performs the actual lock volume operation. It will be called - by anyone wishing to try to protect the volume for a long duration. PNP - operations are such a user. - - The volume must be held exclusive by the caller. - -Arguments: - - Vcb - The volume being locked. - - FileObject - File corresponding to the handle locking the volume. If this - is not specified, a system lock is assumed. - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - KIRQL SavedIrql; - NTSTATUS FinalStatus = (FileObject? STATUS_ACCESS_DENIED: STATUS_DEVICE_BUSY); - ULONG RemainingUserReferences = (FileObject? 1: 0); - - // - // The cleanup count for the volume only reflects the fileobject that - // will lock the volume. Otherwise, we must fail the request. - // - // Since the only cleanup is for the provided fileobject, we will try - // to get rid of all of the other user references. If there is only one - // remaining after the purge then we can allow the volume to be locked. - // - - CdPurgeVolume( IrpContext, Vcb, FALSE ); - - // - // Now back out of our synchronization and wait for the lazy writer - // to finish off any lazy closes that could have been outstanding. - // - // Since we purged, we know that the lazy writer will issue all - // possible lazy closes in the next tick - if we hadn't, an otherwise - // unopened file with a large amount of dirty data could have hung - // around for a while as the data trickled out to the disk. - // - // This is even more important now since we send notification to - // alert other folks that this style of check is about to happen so - // that they can close their handles. We don't want to enter a fast - // race with the lazy writer tearing down his references to the file. - // - - CdReleaseVcb( IrpContext, Vcb ); - - Status = CcWaitForCurrentLazyWriterActivity(); - - // - // This is intentional. If we were able to get the Vcb before, just - // wait for it and take advantage of knowing that it is OK to leave - // the flag up. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - if (!NT_SUCCESS( Status )) { - - return Status; - } - - CdFspClose( Vcb ); - - // - // If the volume is already explicitly locked then fail. We use the - // Vpb locked flag as an 'explicit lock' flag in the same way as Fat. - // - - IoAcquireVpbSpinLock( &SavedIrql ); - - if (!FlagOn( Vcb->Vpb->Flags, VPB_LOCKED ) && - (Vcb->VcbCleanup == RemainingUserReferences) && - (Vcb->VcbUserReference == CDFS_RESIDUAL_USER_REFERENCE + RemainingUserReferences)) { - - SetFlag( Vcb->VcbState, VCB_STATE_LOCKED ); - SetFlag( Vcb->Vpb->Flags, VPB_LOCKED); - Vcb->VolumeLockFileObject = FileObject; - FinalStatus = STATUS_SUCCESS; - } - - IoReleaseVpbSpinLock( SavedIrql ); - - return FinalStatus; -} - - -NTSTATUS -CdUnlockVolumeInternal ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_OBJECT FileObject OPTIONAL - ) - -/*++ - -Routine Description: - - This routine performs the actual unlock volume operation. - - The volume must be held exclusive by the caller. - -Arguments: - - Vcb - The volume being locked. - - FileObject - File corresponding to the handle locking the volume. If this - is not specified, a system lock is assumed. - -Return Value: - - NTSTATUS - The return status for the operation - - Attempting to remove a system lock that did not exist is OK. - ---*/ - -{ - NTSTATUS Status = STATUS_NOT_LOCKED; - KIRQL SavedIrql; - - // - // Note that we check the VPB_LOCKED flag here rather than the Vcb - // lock flag. The Vpb flag is only set for an explicit lock request, not - // for the implicit lock obtained on a volume open with zero share mode. - // - - IoAcquireVpbSpinLock( &SavedIrql ); - - if (FlagOn(Vcb->Vpb->Flags, VPB_LOCKED) && - (FileObject == Vcb->VolumeLockFileObject)) { - - ClearFlag( Vcb->VcbState, VCB_STATE_LOCKED ); - ClearFlag( Vcb->Vpb->Flags, VPB_LOCKED); - Vcb->VolumeLockFileObject = NULL; - Status = STATUS_SUCCESS; - } - - IoReleaseVpbSpinLock( SavedIrql ); - - return Status; -} - - -NTSTATUS -CdCommonFsControl ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the common routine for doing FileSystem control operations called - by both the fsd and fsp threads - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - // - // Get a pointer to the current Irp stack location - // - - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PAGED_CODE(); - - // - // We know this is a file system control so we'll case on the - // minor function, and call a internal worker routine to complete - // the irp. - // - - switch (IrpSp->MinorFunction) { - - case IRP_MN_USER_FS_REQUEST: - - Status = CdUserFsctl( IrpContext, Irp ); - break; - - case IRP_MN_MOUNT_VOLUME: - - Status = CdMountVolume( IrpContext, Irp ); - break; - - case IRP_MN_VERIFY_VOLUME: - - Status = CdVerifyVolume( IrpContext, Irp ); - break; - - default: - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST ); - Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdUserFsctl ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) -/*++ - -Routine Description: - - This is the common routine for implementing the user's requests made - through NtFsControlFile. - -Arguments: - - Irp - Supplies the Irp being processed - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PAGED_CODE(); - - // - // Case on the control code. - // - - switch ( IrpSp->Parameters.FileSystemControl.FsControlCode ) { - - case FSCTL_REQUEST_OPLOCK_LEVEL_1 : - case FSCTL_REQUEST_OPLOCK_LEVEL_2 : - case FSCTL_REQUEST_BATCH_OPLOCK : - case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE : - case FSCTL_OPBATCH_ACK_CLOSE_PENDING : - case FSCTL_OPLOCK_BREAK_NOTIFY : - case FSCTL_OPLOCK_BREAK_ACK_NO_2 : - case FSCTL_REQUEST_FILTER_OPLOCK : - - Status = CdOplockRequest( IrpContext, Irp ); - break; - - case FSCTL_LOCK_VOLUME : - - Status = CdLockVolume( IrpContext, Irp ); - break; - - case FSCTL_UNLOCK_VOLUME : - - Status = CdUnlockVolume( IrpContext, Irp ); - break; - - case FSCTL_DISMOUNT_VOLUME : - - Status = CdDismountVolume( IrpContext, Irp ); - break; - - case FSCTL_IS_VOLUME_DIRTY : - - Status = CdIsVolumeDirty( IrpContext, Irp ); - break; - - case FSCTL_IS_VOLUME_MOUNTED : - - Status = CdIsVolumeMounted( IrpContext, Irp ); - break; - - case FSCTL_IS_PATHNAME_VALID : - - Status = CdIsPathnameValid( IrpContext, Irp ); - break; - - case FSCTL_INVALIDATE_VOLUMES : - - Status = CdInvalidateVolumes( IrpContext, Irp ); - break; - - - // - // We don't support any of the known or unknown requests. - // - - default: - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST ); - Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - - return Status; -} - - -VOID -CdReMountOldVcb( - IN PIRP_CONTEXT IrpContext, - IN PVCB OldVcb, - IN PVCB NewVcb, - IN PDEVICE_OBJECT DeviceObjectWeTalkTo - ) -{ - KIRQL SavedIrql; - - ObDereferenceObject( OldVcb->TargetDeviceObject ); - - IoAcquireVpbSpinLock( &SavedIrql ); - - NewVcb->Vpb->RealDevice->Vpb = OldVcb->Vpb; - - OldVcb->Vpb->RealDevice = NewVcb->Vpb->RealDevice; - OldVcb->TargetDeviceObject = DeviceObjectWeTalkTo; - - CdUpdateVcbCondition( OldVcb, VcbMounted); - CdUpdateMediaChangeCount( OldVcb, NewVcb->MediaChangeCount); - - ClearFlag( OldVcb->VcbState, VCB_STATE_VPB_NOT_ON_DEVICE); - - IoReleaseVpbSpinLock( SavedIrql ); -} - - -// -// Local support routine -// - -NTSTATUS -CdMountVolume ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine performs the mount volume operation. It is responsible for - either completing of enqueuing the input Irp. - - Its job is to verify that the volume denoted in the IRP is a Cdrom volume, - and create the VCB and root DCB structures. The algorithm it - uses is essentially as follows: - - 1. Create a new Vcb Structure, and initialize it enough to do I/O - through the on-disk volume descriptors. - - 2. Read the disk and check if it is a Cdrom volume. - - 3. If it is not a Cdrom volume then delete the Vcb and - complete the IRP back with an appropriate status. - - 4. Check if the volume was previously mounted and if it was then do a - remount operation. This involves deleting the VCB, hook in the - old VCB, and complete the IRP. - - 5. Otherwise create a Vcb and root DCB for each valid volume descriptor. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - - PVOLUME_DEVICE_OBJECT VolDo = NULL; - PVCB Vcb = NULL; - PVCB OldVcb; - - BOOLEAN FoundPvd = FALSE; - BOOLEAN SetDoVerifyOnFail; - - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - PDEVICE_OBJECT DeviceObjectWeTalkTo = IrpSp->Parameters.MountVolume.DeviceObject; - PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb; - - PFILE_OBJECT FileObjectToNotify = NULL; - - ULONG BlockFactor; - DISK_GEOMETRY DiskGeometry; - - IO_SCSI_CAPABILITIES Capabilities; - - IO_STATUS_BLOCK Iosb; - - PCHAR RawIsoVd = NULL; - - PCDROM_TOC CdromToc = NULL; - ULONG TocLength = 0; - ULONG TocTrackCount = 0; - ULONG TocDiskFlags = 0; - ULONG MediaChangeCount = 0; - - PAGED_CODE(); - - // - // Check that we are talking to a Cdrom device. This request should - // always be waitable. - // - - ASSERT( Vpb->RealDevice->DeviceType == FILE_DEVICE_CD_ROM ); - ASSERT( FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )); - - // - // Update the real device in the IrpContext from the Vpb. There was no available - // file object when the IrpContext was created. - // - - IrpContext->RealDevice = Vpb->RealDevice; - - SetDoVerifyOnFail = CdRealDevNeedsVerify( IrpContext->RealDevice); - - // - // Check if we have disabled the mount process. - // - - if (CdDisable) { - - CdCompleteRequest( IrpContext, Irp, STATUS_UNRECOGNIZED_VOLUME ); - return STATUS_UNRECOGNIZED_VOLUME; - } - - // - // Do a CheckVerify here to lift the MediaChange ticker from the driver - // - - Status = CdPerformDevIoCtrl( IrpContext, - IOCTL_CDROM_CHECK_VERIFY, - DeviceObjectWeTalkTo, - &MediaChangeCount, - sizeof(ULONG), - FALSE, - TRUE, - &Iosb ); - - if (!NT_SUCCESS( Status )) { - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; - } - - if (Iosb.Information != sizeof(ULONG)) { - - // - // Be safe about the count in case the driver didn't fill it in - // - - MediaChangeCount = 0; - } - - // - // Now let's make Jeff delirious and call to get the disk geometry. This - // will fix the case where the first change line is swallowed. - // - - Status = CdPerformDevIoCtrl( IrpContext, - IOCTL_CDROM_GET_DRIVE_GEOMETRY, - DeviceObjectWeTalkTo, - &DiskGeometry, - sizeof( DISK_GEOMETRY ), - FALSE, - TRUE, - NULL ); - - // - // Return insufficient sources to our caller. - // - - if (Status == STATUS_INSUFFICIENT_RESOURCES) { - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; - } - - // - // Now check the block factor for addressing the volume descriptors. - // If the call for the disk geometry failed then assume there is one - // block per sector. - // - - BlockFactor = 1; - - if (NT_SUCCESS( Status ) && - (DiskGeometry.BytesPerSector != 0) && - (DiskGeometry.BytesPerSector < SECTOR_SIZE)) { - - BlockFactor = SECTOR_SIZE / DiskGeometry.BytesPerSector; - } - - // - // Acquire the global resource to do mount operations. - // - - CdAcquireCdData( IrpContext ); - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Allocate a buffer to query the TOC. - // - - CdromToc = FsRtlAllocatePoolWithTag( CdPagedPool, - sizeof( CDROM_TOC ), - TAG_CDROM_TOC ); - - RtlZeroMemory( CdromToc, sizeof( CDROM_TOC )); - - // - // Do a quick check to see if there any Vcb's which can be removed. - // - - CdScanForDismountedVcb( IrpContext ); - - // - // Get our device object and alignment requirement. - // - - Status = IoCreateDevice( CdData.DriverObject, - sizeof( VOLUME_DEVICE_OBJECT ) - sizeof( DEVICE_OBJECT ), - NULL, - FILE_DEVICE_CD_ROM_FILE_SYSTEM, - 0, - FALSE, - (PDEVICE_OBJECT *) &VolDo ); - - if (!NT_SUCCESS( Status )) { try_leave( Status ); } - - // - // Our alignment requirement is the larger of the processor alignment requirement - // already in the volume device object and that in the DeviceObjectWeTalkTo - // - - if (DeviceObjectWeTalkTo->AlignmentRequirement > VolDo->DeviceObject.AlignmentRequirement) { - - VolDo->DeviceObject.AlignmentRequirement = DeviceObjectWeTalkTo->AlignmentRequirement; - } - - // - // We must initialize the stack size in our device object before - // the following reads, because the I/O system has not done it yet. - // - - ((PDEVICE_OBJECT) VolDo)->StackSize = (CCHAR) (DeviceObjectWeTalkTo->StackSize + 1); - - ClearFlag( VolDo->DeviceObject.Flags, DO_DEVICE_INITIALIZING ); - - // - // Initialize the overflow queue for the volume - // - - VolDo->OverflowQueueCount = 0; - InitializeListHead( &VolDo->OverflowQueue ); - - VolDo->PostedRequestCount = 0; - KeInitializeSpinLock( &VolDo->OverflowQueueSpinLock ); - - // - // Let's query for the Toc now and handle any error we get from this operation. - // - - Status = CdProcessToc( IrpContext, - DeviceObjectWeTalkTo, - CdromToc, - &TocLength, - &TocTrackCount, - &TocDiskFlags ); - - // - // If we failed to read the TOC, then bail out. Probably blank media. - // - - if (Status != STATUS_SUCCESS) { - - try_leave( Status ); - } - - // - // Now before we can initialize the Vcb we need to set up the - // device object field in the VPB to point to our new volume device - // object. - // - - Vpb->DeviceObject = (PDEVICE_OBJECT) VolDo; - - // - // Initialize the Vcb. This routine will raise on an allocation - // failure. - // - - CdInitializeVcb( IrpContext, - &VolDo->Vcb, - DeviceObjectWeTalkTo, - Vpb, - CdromToc, - TocLength, - TocTrackCount, - TocDiskFlags, - BlockFactor, - MediaChangeCount ); - - // - // Show that we initialized the Vcb and can cleanup with the Vcb. - // - - Vcb = &VolDo->Vcb; - VolDo = NULL; - Vpb = NULL; - CdromToc = NULL; - - // - // Store the Vcb in the IrpContext as we didn't have one before. - // - - IrpContext->Vcb = Vcb; - - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - // - // Let's reference the Vpb to make sure we are the one to - // have the last dereference. - // - - Vcb->Vpb->ReferenceCount += 1; - - // - // Clear the verify bit for the start of mount. - // - - CdMarkRealDevVerifyOk( Vcb->Vpb->RealDevice); - - if (!FlagOn( Vcb->VcbState, VCB_STATE_AUDIO_DISK)) { - - // - // Allocate a buffer to read in the volume descriptors. We allocate a full - // page to make sure we don't hit any alignment problems. - // - - RawIsoVd = FsRtlAllocatePoolWithTag( CdNonPagedPool, - ROUND_TO_PAGES( SECTOR_SIZE ), - TAG_VOL_DESC ); - - // - // Try to find the primary volume descriptor. - // - - FoundPvd = CdFindPrimaryVd( IrpContext, - Vcb, - RawIsoVd, - BlockFactor, - TRUE, - FALSE ); - - if (!FoundPvd) { - - // - // We failed to find a valid VD in the data track, but there were also - // audio tracks on this disc, so we'll try to mount it as an audio CD. - // Since we're always last in the mount order, we won't be preventing - // any other FS from trying to mount the data track. However if the - // data track was at the start of the disc, then we abort, to avoid - // having to filter it from our synthesised directory listing later. We - // already filtered off any data track at the end. - // - - if (!(TocDiskFlags & CDROM_DISK_AUDIO_TRACK) || - BooleanFlagOn( Vcb->CdromToc->TrackData[0].Control, TOC_DATA_TRACK)) { - - try_leave( Status = STATUS_UNRECOGNIZED_VOLUME); - } - - SetFlag( Vcb->VcbState, VCB_STATE_AUDIO_DISK | VCB_STATE_CDXA ); - - CdFreePool( &RawIsoVd ); - RawIsoVd = NULL; - } - } - - // - // Look and see if there is a secondary volume descriptor we want to - // use. - // - - if (FoundPvd) { - - // - // Store the primary volume descriptor in the second half of - // RawIsoVd. Then if our search for a secondary fails we can - // recover this immediately. - // - - RtlCopyMemory( Add2Ptr( RawIsoVd, SECTOR_SIZE, PVOID ), - RawIsoVd, - SECTOR_SIZE ); - - // - // We have the initial volume descriptor. Locate a secondary - // volume descriptor if present. - // - - CdFindActiveVolDescriptor( IrpContext, - Vcb, - RawIsoVd, - FALSE); - } - - // - // Check if this is a remount operation. If so then clean up - // the data structures passed in and created here. - // - - if (CdIsRemount( IrpContext, Vcb, &OldVcb )) { - - //KIRQL SavedIrql; /* ReactOS Change: GCC Unused variable */ - - ASSERT( NULL != OldVcb->SwapVpb ); - - // - // Link the old Vcb to point to the new device object that we - // should be talking to, dereferencing the previous. Call a - // nonpaged routine to do this since we take the Vpb spinlock. - // - - CdReMountOldVcb( IrpContext, - OldVcb, - Vcb, - DeviceObjectWeTalkTo); - - // - // See if we will need to provide notification of the remount. This is the readonly - // filesystem's form of dismount/mount notification - we promise that whenever a - // volume is "dismounted", that a mount notification will occur when it is revalidated. - // Note that we do not send mount on normal remounts - that would duplicate the media - // arrival notification of the device driver. - // - - if (FlagOn( OldVcb->VcbState, VCB_STATE_NOTIFY_REMOUNT )) { - - ClearFlag( OldVcb->VcbState, VCB_STATE_NOTIFY_REMOUNT ); - - FileObjectToNotify = OldVcb->RootIndexFcb->FileObject; - ObReferenceObject( FileObjectToNotify ); - } - - try_leave( Status = STATUS_SUCCESS ); - } - - // - // This is a new mount. Go ahead and initialize the - // Vcb from the volume descriptor. - // - - CdUpdateVcbFromVolDescriptor( IrpContext, - Vcb, - RawIsoVd ); - - // - // Drop an extra reference on the root dir file so we'll be able to send - // notification. - // - - if (Vcb->RootIndexFcb) { - - FileObjectToNotify = Vcb->RootIndexFcb->FileObject; - ObReferenceObject( FileObjectToNotify ); - } - - // - // Now check the maximum transfer limits on the device in case we - // get raw reads on this volume. - // - - Status = CdPerformDevIoCtrl( IrpContext, - IOCTL_SCSI_GET_CAPABILITIES, - DeviceObjectWeTalkTo, - &Capabilities, - sizeof( IO_SCSI_CAPABILITIES ), - FALSE, - TRUE, - NULL ); - - if (NT_SUCCESS(Status)) { - - Vcb->MaximumTransferRawSectors = Capabilities.MaximumTransferLength / RAW_SECTOR_SIZE; - Vcb->MaximumPhysicalPages = Capabilities.MaximumPhysicalPages; - - } else { - - // - // This should never happen, but we can safely assume 64k and 16 pages. - // - - Vcb->MaximumTransferRawSectors = (64 * 1024) / RAW_SECTOR_SIZE; - Vcb->MaximumPhysicalPages = 16; - } - - // - // The new mount is complete. Remove the additional references on this - // Vcb and the device we are mounted on top of. - // - - Vcb->VcbReference -= CDFS_RESIDUAL_REFERENCE; - ASSERT( Vcb->VcbReference == CDFS_RESIDUAL_REFERENCE ); - - ObDereferenceObject( Vcb->TargetDeviceObject ); - - CdUpdateVcbCondition( Vcb, VcbMounted); - - CdReleaseVcb( IrpContext, Vcb ); - Vcb = NULL; - - Status = STATUS_SUCCESS; - - } finally { - - // - // Free the TOC buffer if not in the Vcb. - // - - if (CdromToc != NULL) { - - CdFreePool( &CdromToc ); - } - - // - // Free the sector buffer if allocated. - // - - if (RawIsoVd != NULL) { - - CdFreePool( &RawIsoVd ); - } - - // - // If we are not mounting the device, then set the verify bit again. - // - - if ((AbnormalTermination() || (Status != STATUS_SUCCESS)) && - SetDoVerifyOnFail) { - - CdMarkRealDevForVerify( IrpContext->RealDevice); - } - - // - // If we didn't complete the mount then cleanup any remaining structures. - // - - if (Vpb != NULL) { Vpb->DeviceObject = NULL; } - - if (Vcb != NULL) { - - // - // Make sure there is no Vcb in the IrpContext since it could go away - // - - IrpContext->Vcb = NULL; - - Vcb->VcbReference -= CDFS_RESIDUAL_REFERENCE; - - if (CdDismountVcb( IrpContext, Vcb )) { - - CdReleaseVcb( IrpContext, Vcb ); - } - - } else if (VolDo != NULL) { - - IoDeleteDevice( (PDEVICE_OBJECT) VolDo ); - } - - // - // Release the global resource. - // - - CdReleaseCdData( IrpContext ); - } - - // - // Now send mount notification. - // - - if (FileObjectToNotify) { - - FsRtlNotifyVolumeEvent( FileObjectToNotify, FSRTL_VOLUME_MOUNT ); - ObDereferenceObject( FileObjectToNotify ); - } - - // - // Complete the request if no exception. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdVerifyVolume ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine performs the verify volume operation. It is responsible for - either completing of enqueuing the input Irp. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - PVPB Vpb = IrpSp->Parameters.VerifyVolume.Vpb; - PVCB Vcb = &((PVOLUME_DEVICE_OBJECT) IrpSp->Parameters.VerifyVolume.DeviceObject)->Vcb; - - PCHAR RawIsoVd = NULL; - - PCDROM_TOC CdromToc = NULL; - ULONG TocLength = 0; - ULONG TocTrackCount = 0; - ULONG TocDiskFlags = 0; - - ULONG MediaChangeCount = Vcb->MediaChangeCount; - - PFILE_OBJECT FileObjectToNotify = NULL; - - BOOLEAN ReturnError; - BOOLEAN ReleaseVcb = FALSE; - - IO_STATUS_BLOCK Iosb; - - STRING AnsiLabel; - UNICODE_STRING UnicodeLabel; - - WCHAR VolumeLabel[ VOLUME_ID_LENGTH ]; - ULONG VolumeLabelLength; - - ULONG Index; - - NTSTATUS Status; - - PAGED_CODE(); - - // - // We check that we are talking to a Cdrom device. - // - - ASSERT( Vpb->RealDevice->DeviceType == FILE_DEVICE_CD_ROM ); - ASSERT( FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )); - - // - // Update the real device in the IrpContext from the Vpb. There was no available - // file object when the IrpContext was created. - // - - IrpContext->RealDevice = Vpb->RealDevice; - - // - // Acquire the global resource to synchronise against mounts and teardown, - // finally clause releases. - // - - CdAcquireCdData( IrpContext ); - - try { - - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - ReleaseVcb = TRUE; - - // - // Verify that there is a disk here. - // - - Status = CdPerformDevIoCtrl( IrpContext, - IOCTL_CDROM_CHECK_VERIFY, - Vcb->TargetDeviceObject, - &MediaChangeCount, - sizeof(ULONG), - FALSE, - TRUE, - &Iosb ); - - if (!NT_SUCCESS( Status )) { - - // - // If we will allow a raw mount then return WRONG_VOLUME to - // allow the volume to be mounted by raw. - // - - if (FlagOn( IrpSp->Flags, SL_ALLOW_RAW_MOUNT )) { - - Status = STATUS_WRONG_VOLUME; - } - - try_return( Status ); - } - - if (Iosb.Information != sizeof(ULONG)) { - - // - // Be safe about the count in case the driver didn't fill it in - // - - MediaChangeCount = 0; - } - - // - // Verify that the device actually saw a change. If the driver does not - // support the MCC, then we must verify the volume in any case. - // - - if (MediaChangeCount == 0 || - (Vcb->MediaChangeCount != MediaChangeCount)) { - - // - // Allocate a buffer to query the TOC. - // - - CdromToc = FsRtlAllocatePoolWithTag( CdPagedPool, - sizeof( CDROM_TOC ), - TAG_CDROM_TOC ); - - RtlZeroMemory( CdromToc, sizeof( CDROM_TOC )); - - // - // Let's query for the Toc now and handle any error we get from this operation. - // - - Status = CdProcessToc( IrpContext, - Vcb->TargetDeviceObject, - CdromToc, - &TocLength, - &TocTrackCount, - &TocDiskFlags ); - - // - // If we failed to read the TOC, then give up now. Drives will fail - // a TOC read on, for example, erased CD-RW media. - // - - if (Status != STATUS_SUCCESS) { - - // - // For any errors other than no media and not ready, commute the - // status to ensure that the current VPB is kicked off the device - // below - there is probably blank media in the drive, since we got - // further than the check verify. - // - - if (!CdIsRawDevice( IrpContext, Status )) { - - Status = STATUS_WRONG_VOLUME; - } - - try_return( Status ); - - // - // We got a TOC. Verify that it matches the previous Toc. - // - - } else if ((Vcb->TocLength != TocLength) || - (Vcb->TrackCount != TocTrackCount) || - (Vcb->DiskFlags != TocDiskFlags) || - !RtlEqualMemory( CdromToc, - Vcb->CdromToc, - TocLength )) { - - try_return( Status = STATUS_WRONG_VOLUME ); - } - - // - // If the disk to verify is an audio disk then we already have a - // match. Otherwise we need to check the volume descriptor. - // - - if (!FlagOn( Vcb->VcbState, VCB_STATE_AUDIO_DISK )) { - - // - // Allocate a buffer for the sector buffer. - // - - RawIsoVd = FsRtlAllocatePoolWithTag( CdNonPagedPool, - ROUND_TO_PAGES( 2 * SECTOR_SIZE ), - TAG_VOL_DESC ); - - // - // Read the primary volume descriptor for this volume. If we - // get an io error and this verify was a the result of DASD open, - // commute the Io error to STATUS_WRONG_VOLUME. Note that if we currently - // expect a music disk then this request should fail. - // - - ReturnError = FALSE; - - if (FlagOn( IrpSp->Flags, SL_ALLOW_RAW_MOUNT )) { - - ReturnError = TRUE; - } - - if (!CdFindPrimaryVd( IrpContext, - Vcb, - RawIsoVd, - Vcb->BlockFactor, - ReturnError, - TRUE )) { - - // - // If the previous Vcb did not represent a raw disk - // then show this volume was dismounted. - // - - try_return( Status = STATUS_WRONG_VOLUME ); - - } - else { - - // - // Look for a supplementary VD. - // - // Store the primary volume descriptor in the second half of - // RawIsoVd. Then if our search for a secondary fails we can - // recover this immediately. - // - - RtlCopyMemory( Add2Ptr( RawIsoVd, SECTOR_SIZE, PVOID ), - RawIsoVd, - SECTOR_SIZE ); - - // - // We have the initial volume descriptor. Locate a secondary - // volume descriptor if present. - // - - CdFindActiveVolDescriptor( IrpContext, - Vcb, - RawIsoVd, - TRUE); - // - // Compare the serial numbers. If they don't match, set the - // status to wrong volume. - // - - if (Vpb->SerialNumber != CdSerial32( RawIsoVd, SECTOR_SIZE )) { - - try_return( Status = STATUS_WRONG_VOLUME ); - } - - // - // Verify the volume labels. - // - - if (!FlagOn( Vcb->VcbState, VCB_STATE_JOLIET )) { - - // - // Compute the length of the volume name - // - - AnsiLabel.Buffer = (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ); /* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - AnsiLabel.MaximumLength = AnsiLabel.Length = VOLUME_ID_LENGTH; - - UnicodeLabel.MaximumLength = VOLUME_ID_LENGTH * sizeof( WCHAR ); - UnicodeLabel.Buffer = VolumeLabel; - - // - // Convert this to unicode. If we get any error then use a name - // length of zero. - // - - VolumeLabelLength = 0; - - if (NT_SUCCESS( RtlOemStringToCountedUnicodeString( &UnicodeLabel, - &AnsiLabel, - FALSE ))) { - - VolumeLabelLength = UnicodeLabel.Length; - } - - // - // We need to convert from big-endian to little endian. - // - - } else { - - CdConvertBigToLittleEndian( IrpContext, - (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ),/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - VOLUME_ID_LENGTH, - (PCHAR) VolumeLabel ); - - VolumeLabelLength = VOLUME_ID_LENGTH; - } - - // - // Strip the trailing spaces or zeroes from the name. - // - - Index = VolumeLabelLength / sizeof( WCHAR ); - - while (Index > 0) { - - if ((VolumeLabel[ Index - 1 ] != L'\0') && - (VolumeLabel[ Index - 1 ] != L' ')) { - - break; - } - - Index -= 1; - } - - // - // Now set the final length for the name. - // - - VolumeLabelLength = (USHORT) (Index * sizeof( WCHAR )); - - // - // Now check that the label matches. - // - if ((Vpb->VolumeLabelLength != VolumeLabelLength) || - !RtlEqualMemory( Vpb->VolumeLabel, - VolumeLabel, - VolumeLabelLength )) { - - try_return( Status = STATUS_WRONG_VOLUME ); - } - } - } - } - - // - // The volume is OK, clear the verify bit. - // - - CdUpdateVcbCondition( Vcb, VcbMounted); - - CdMarkRealDevVerifyOk( Vpb->RealDevice); - - // - // See if we will need to provide notification of the remount. This is the readonly - // filesystem's form of dismount/mount notification. - // - - if (FlagOn( Vcb->VcbState, VCB_STATE_NOTIFY_REMOUNT )) { - - ClearFlag( Vcb->VcbState, VCB_STATE_NOTIFY_REMOUNT ); - - FileObjectToNotify = Vcb->RootIndexFcb->FileObject; - ObReferenceObject( FileObjectToNotify ); - } - - try_exit: NOTHING; - - // - // Update the media change count to note that we have verified the volume - // at this value - regardless of the outcome. - // - - CdUpdateMediaChangeCount( Vcb, MediaChangeCount); - - // - // If we got the wrong volume then free any remaining XA sector in - // the current Vcb. Also mark the Vcb as not mounted. - // - - if (Status == STATUS_WRONG_VOLUME) { - - CdUpdateVcbCondition( Vcb, VcbNotMounted); - - if (Vcb->XASector != NULL) { - - CdFreePool( &Vcb->XASector ); - Vcb->XASector = 0; - Vcb->XADiskOffset = 0; - } - - // - // Now, if there are no user handles to the volume, try to spark - // teardown by purging the volume. - // - - if (Vcb->VcbCleanup == 0) { - - if (NT_SUCCESS( CdPurgeVolume( IrpContext, Vcb, FALSE ))) { - - ReleaseVcb = CdCheckForDismount( IrpContext, Vcb, FALSE ); - } - } - } - - } finally { - - // - // Free the TOC buffer if allocated. - // - - if (CdromToc != NULL) { - - CdFreePool( &CdromToc ); - } - - if (RawIsoVd != NULL) { - - CdFreePool( &RawIsoVd ); - } - - if (ReleaseVcb) { - - CdReleaseVcb( IrpContext, Vcb ); - } - - CdReleaseCdData( IrpContext ); - } - - // - // Now send mount notification. - // - - if (FileObjectToNotify) { - - FsRtlNotifyVolumeEvent( FileObjectToNotify, FSRTL_VOLUME_MOUNT ); - ObDereferenceObject( FileObjectToNotify ); - } - - // - // Complete the request if no exception. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdOplockRequest ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the common routine to handle oplock requests made via the - NtFsControlFile call. - -Arguments: - - Irp - Supplies the Irp being processed - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - PFCB Fcb; - PCCB Ccb; - - ULONG OplockCount = 0; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PAGED_CODE(); - - // - // We only permit oplock requests on files. - // - - if (CdDecodeFileObject( IrpContext, - IrpSp->FileObject, - &Fcb, - &Ccb ) != UserFileOpen ) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - // - // Make this a waitable Irpcontext so we don't fail to acquire - // the resources. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); - ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST ); - - // - // Switch on the function control code. We grab the Fcb exclusively - // for oplock requests, shared for oplock break acknowledgement. - // - - switch (IrpSp->Parameters.FileSystemControl.FsControlCode) { - - case FSCTL_REQUEST_OPLOCK_LEVEL_1 : - case FSCTL_REQUEST_OPLOCK_LEVEL_2 : - case FSCTL_REQUEST_BATCH_OPLOCK : - case FSCTL_REQUEST_FILTER_OPLOCK : - - CdAcquireFcbExclusive( IrpContext, Fcb, FALSE ); - - if (IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_2) { - - if (Fcb->FileLock != NULL) { - - OplockCount = (ULONG) FsRtlAreThereCurrentFileLocks( Fcb->FileLock ); - } - - } else { - - OplockCount = Fcb->FcbCleanup; - } - - break; - - case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE: - case FSCTL_OPBATCH_ACK_CLOSE_PENDING: - case FSCTL_OPLOCK_BREAK_NOTIFY: - case FSCTL_OPLOCK_BREAK_ACK_NO_2: - - CdAcquireFcbShared( IrpContext, Fcb, FALSE ); - break; - - default: - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - // - // Use a try finally to free the Fcb. - // - - try { - - // - // Verify the Fcb. - // - - CdVerifyFcbOperation( IrpContext, Fcb ); - - // - // Call the FsRtl routine to grant/acknowledge oplock. - // - - Status = FsRtlOplockFsctrl( &Fcb->Oplock, - Irp, - OplockCount ); - - // - // Set the flag indicating if Fast I/O is possible - // - - CdLockFcb( IrpContext, Fcb ); - Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); - CdUnlockFcb( IrpContext, Fcb ); - - // - // The oplock package will complete the Irp. - // - - Irp = NULL; - - } finally { - - // - // Release all of our resources - // - - CdReleaseFcb( IrpContext, Fcb ); - } - - // - // Complete the request if there was no exception. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdLockVolume ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine performs the lock volume operation. It is responsible for - either completing of enqueuing the input Irp. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - - PAGED_CODE(); - - // - // Decode the file object, the only type of opens we accept are - // user volume opens. - // - - if (CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ) != UserVolumeOpen) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - - return STATUS_INVALID_PARAMETER; - } - - // - // Send our notification so that folks that like to hold handles on - // volumes can get out of the way. - // - - FsRtlNotifyVolumeEvent( IrpSp->FileObject, FSRTL_VOLUME_LOCK ); - - // - // Acquire exclusive access to the Vcb. - // - - Vcb = Fcb->Vcb; - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - try { - - // - // Verify the Vcb. - // - - CdVerifyVcb( IrpContext, Vcb ); - - Status = CdLockVolumeInternal( IrpContext, Vcb, IrpSp->FileObject ); - - } finally { - - // - // Release the Vcb. - // - - CdReleaseVcb( IrpContext, Vcb ); - - if (AbnormalTermination() || !NT_SUCCESS( Status )) { - - FsRtlNotifyVolumeEvent( IrpSp->FileObject, FSRTL_VOLUME_LOCK_FAILED ); - } - } - - // - // Complete the request if there haven't been any exceptions. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdUnlockVolume ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine performs the unlock volume operation. It is responsible for - either completing of enqueuing the input Irp. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - - PAGED_CODE(); - - // - // Decode the file object, the only type of opens we accept are - // user volume opens. - // - - if (CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ) != UserVolumeOpen ) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - // - // Acquire exclusive access to the Vcb. - // - - Vcb = Fcb->Vcb; - - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - // - // We won't check for a valid Vcb for this request. An unlock will always - // succeed on a locked volume. - // - - Status = CdUnlockVolumeInternal( IrpContext, Vcb, IrpSp->FileObject ); - - // - // Release all of our resources - // - - CdReleaseVcb( IrpContext, Vcb ); - - // - // Send notification that the volume is avaliable. - // - - if (NT_SUCCESS( Status )) { - - FsRtlNotifyVolumeEvent( IrpSp->FileObject, FSRTL_VOLUME_UNLOCK ); - } - - // - // Complete the request if there haven't been any exceptions. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; -} - - - -// -// Local support routine -// - -NTSTATUS -CdDismountVolume ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine performs the dismount volume operation. It is responsible for - either completing of enqueuing the input Irp. We only dismount a volume which - has been locked. The intent here is that someone has locked the volume (they are the - only remaining handle). We set the verify bit here and the user will close his handle. - We will dismount a volume with no user's handles in the verify path. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PVCB Vcb; - PFCB Fcb; - PCCB Ccb; - - PAGED_CODE(); - - if (CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ) != UserVolumeOpen ) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - Vcb = Fcb->Vcb; - - // - // Make this request waitable. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT); - - // - // Acquire exclusive access to the Vcb, and take the global resource to - // sync. against mounts, verifies etc. - // - - CdAcquireCdData( IrpContext ); - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - // - // Mark the volume as needs to be verified, but only do it if - // the vcb is locked by this handle and the volume is currently mounted. - // - - if (Vcb->VcbCondition != VcbMounted) { - - Status = STATUS_VOLUME_DISMOUNTED; - - } else { - - // - // Invalidate the volume right now. - // - // The intent here is to make every subsequent operation - // on the volume fail and grease the rails toward dismount. - // By definition there is no going back from a SURPRISE. - // - - CdLockVcb( IrpContext, Vcb ); - - if (Vcb->VcbCondition != VcbDismountInProgress) { - - CdUpdateVcbCondition( Vcb, VcbInvalid); - } - - CdUnlockVcb( IrpContext, Vcb ); - - // - // Set flag to tell the close path that we want to force dismount - // the volume when this handle is closed. - // - - SetFlag( Ccb->Flags, CCB_FLAG_DISMOUNT_ON_CLOSE); - - Status = STATUS_SUCCESS; - } - - // - // Release all of our resources - // - - CdReleaseVcb( IrpContext, Vcb ); - CdReleaseCdData( IrpContext); - - // - // Complete the request if there haven't been any exceptions. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; -} - - -// -// Local support routine -// -NTSTATUS /* ReactOS Change: Function did not have a type??? */ -CdIsVolumeDirty ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine determines if a volume is currently dirty. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - PIO_STACK_LOCATION IrpSp; - - TYPE_OF_OPEN TypeOfOpen; - PFCB Fcb; - PCCB Ccb; - - PULONG VolumeState; - - // - // Get the current stack location and extract the output - // buffer information. - // - - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - // - // Get a pointer to the output buffer. - // - - if (Irp->AssociatedIrp.SystemBuffer != NULL) { - - VolumeState = Irp->AssociatedIrp.SystemBuffer; - - } else { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_USER_BUFFER ); - return STATUS_INVALID_USER_BUFFER; - } - - // - // Make sure the output buffer is large enough and then initialize - // the answer to be that the volume isn't dirty. - // - - if (IrpSp->Parameters.FileSystemControl.OutputBufferLength < sizeof(ULONG)) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - *VolumeState = 0; - - // - // Decode the file object - // - - TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ); - - if (TypeOfOpen != UserVolumeOpen) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - if (Fcb->Vcb->VcbCondition != VcbMounted) { - - CdCompleteRequest( IrpContext, Irp, STATUS_VOLUME_DISMOUNTED ); - return STATUS_VOLUME_DISMOUNTED; - } - - // - // Now set up to return the clean state. CDs obviously can never be dirty - // but we want to make sure we have enforced the full semantics of this call. - // - - Irp->IoStatus.Information = sizeof( ULONG ); - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - return STATUS_SUCCESS; -} - - -// -// Local support routine -// - -NTSTATUS -CdIsVolumeMounted ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine determines if a volume is currently mounted. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PFCB Fcb; - PCCB Ccb; - - PAGED_CODE(); - - // - // Decode the file object. - // - - CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ); - - if (Fcb != NULL) { - - // - // Disable PopUps, we want to return any error. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS ); - - // - // Verify the Vcb. This will raise in the error condition. - // - - CdVerifyVcb( IrpContext, Fcb->Vcb ); - } - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - - return STATUS_SUCCESS; -} - - -// -// Local support routine -// - -NTSTATUS -CdIsPathnameValid ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine determines if pathname is a valid CDFS pathname. - We always succeed this request. - -Arguments: - - Irp - Supplies the Irp to process. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - return STATUS_SUCCESS; -} - - -// -// Local support routine -// - -NTSTATUS -CdInvalidateVolumes ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine searches for all the volumes mounted on the same real device - of the current DASD handle, and marks them all bad. The only operation - that can be done on such handles is cleanup and close. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - KIRQL SavedIrql; - - BOOLEAN UnlockVcb = FALSE; - - LUID TcbPrivilege = {SE_TCB_PRIVILEGE, 0}; - - HANDLE Handle; - - PVCB Vcb; - - PLIST_ENTRY Links; - - PFILE_OBJECT FileToMarkBad; - PDEVICE_OBJECT DeviceToMarkBad; - - // - // We only allow the invalidate call to come in on our file system devices. - // - - if (IrpSp->DeviceObject != CdData.FileSystemDeviceObject) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST ); - - return STATUS_INVALID_DEVICE_REQUEST; - } - - // - // Check for the correct security access. - // The caller must have the SeTcbPrivilege. - // - - if (!SeSinglePrivilegeCheck( TcbPrivilege, Irp->RequestorMode )) { - - CdCompleteRequest( IrpContext, Irp, STATUS_PRIVILEGE_NOT_HELD ); - - return STATUS_PRIVILEGE_NOT_HELD; - } - - // - // Try to get a pointer to the device object from the handle passed in. - // - -#if defined(_WIN64) - if (IoIs32bitProcess( Irp )) { - - if (IrpSp->Parameters.FileSystemControl.InputBufferLength != sizeof( UINT32 )) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - Handle = (HANDLE) LongToHandle( *((PUINT32) Irp->AssociatedIrp.SystemBuffer) ); - - } else { -#endif - if (IrpSp->Parameters.FileSystemControl.InputBufferLength != sizeof( HANDLE )) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - Handle = *((PHANDLE) Irp->AssociatedIrp.SystemBuffer); -#if defined(_WIN64) - } -#endif - - Status = ObReferenceObjectByHandle( Handle, - 0, - IoFileObjectType, /* ReactOS Change: GCC/LD Incompatibily with exported kernel data */ - KernelMode, - (PVOID*)&FileToMarkBad, /* ReactOS Change: GCC "passing argument 5 of 'ObReferenceObjectByHandle' from incompatible pointer type" */ - NULL ); - - if (!NT_SUCCESS(Status)) { - - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; - } - - // - // Grab the DeviceObject from the FileObject. - // - - DeviceToMarkBad = FileToMarkBad->DeviceObject; - - // - // We only needed the device object involved, not a reference to the file. - // - - ObDereferenceObject( FileToMarkBad ); - - // - // Make sure this request can wait. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); - ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST ); - - // - // Synchronise with pnp/mount/verify paths. - // - - CdAcquireCdData( IrpContext ); - - // - // Nothing can go wrong now. - // - - // - // Now walk through all the mounted Vcb's looking for candidates to - // mark invalid. - // - // On volumes we mark invalid, check for dismount possibility (which is - // why we have to get the next link so early). - // - - Links = CdData.VcbQueue.Flink; - - while (Links != &CdData.VcbQueue) { - - Vcb = CONTAINING_RECORD( Links, VCB, VcbLinks); - - Links = Links->Flink; - - // - // If we get a match, mark the volume Bad, and also check to - // see if the volume should go away. - // - - CdLockVcb( IrpContext, Vcb ); - - if (Vcb->Vpb->RealDevice == DeviceToMarkBad) { - - // - // Take the VPB spinlock, and look to see if this volume is the - // one currently mounted on the actual device. If it is, pull it - // off immediately. - // - - IoAcquireVpbSpinLock( &SavedIrql ); - - if (DeviceToMarkBad->Vpb == Vcb->Vpb) { - - PVPB NewVpb = Vcb->SwapVpb; - - ASSERT( FlagOn( Vcb->Vpb->Flags, VPB_MOUNTED)); - ASSERT( NULL != NewVpb); - - RtlZeroMemory( NewVpb, sizeof( VPB ) ); - - NewVpb->Type = IO_TYPE_VPB; - NewVpb->Size = sizeof( VPB ); - NewVpb->RealDevice = DeviceToMarkBad; - NewVpb->Flags = FlagOn( DeviceToMarkBad->Vpb->Flags, VPB_REMOVE_PENDING ); - - DeviceToMarkBad->Vpb = NewVpb; - Vcb->SwapVpb = NULL; - } - - IoReleaseVpbSpinLock( SavedIrql ); - - if (Vcb->VcbCondition != VcbDismountInProgress) { - - CdUpdateVcbCondition( Vcb, VcbInvalid); - } - - CdUnlockVcb( IrpContext, Vcb ); - - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE); - - CdPurgeVolume( IrpContext, Vcb, FALSE ); - - UnlockVcb = CdCheckForDismount( IrpContext, Vcb, FALSE ); - - if (UnlockVcb) { - - CdReleaseVcb( IrpContext, Vcb); - } - - } else { - - CdUnlockVcb( IrpContext, Vcb ); - } - } - - CdReleaseCdData( IrpContext ); - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - return STATUS_SUCCESS; -} - - -// -// Local support routine -// - -VOID -CdScanForDismountedVcb ( - IN PIRP_CONTEXT IrpContext - ) - -/*++ - -Routine Description: - - This routine walks through the list of Vcb's looking for any which may - now be deleted. They may have been left on the list because there were - outstanding references. - -Arguments: - -Return Value: - - None - ---*/ - -{ - PVCB Vcb; - PLIST_ENTRY Links; - - PAGED_CODE(); - - // - // Walk through all of the Vcb's attached to the global data. - // - - Links = CdData.VcbQueue.Flink; - - while (Links != &CdData.VcbQueue) { - - Vcb = CONTAINING_RECORD( Links, VCB, VcbLinks ); - - // - // Move to the next link now since the current Vcb may be deleted. - // - - Links = Links->Flink; - - // - // If dismount is already underway then check if this Vcb can - // go away. - // - - if ((Vcb->VcbCondition == VcbDismountInProgress) || - (Vcb->VcbCondition == VcbInvalid) || - ((Vcb->VcbCondition == VcbNotMounted) && (Vcb->VcbReference <= CDFS_RESIDUAL_REFERENCE))) { - - CdCheckForDismount( IrpContext, Vcb, FALSE ); - } - } - - return; -} - - -// -// Local support routine -// - -BOOLEAN -CdFindPrimaryVd ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PCHAR RawIsoVd, - IN ULONG BlockFactor, - IN BOOLEAN ReturnOnError, - IN BOOLEAN VerifyVolume - ) - -/*++ - -Routine Description: - - This routine is called to walk through the volume descriptors looking - for a primary volume descriptor. When/if a primary is found a 32-bit - serial number is generated and stored into the Vpb. We also store the - location of the primary volume descriptor in the Vcb. - -Arguments: - - Vcb - Pointer to the VCB for the volume. - - RawIsoVd - Pointer to a sector buffer which will contain the primary - volume descriptor on exit, if successful. - - BlockFactor - Block factor used by the current device for the TableOfContents. - - ReturnOnError - Indicates that we should raise on I/O errors rather than - returning a FALSE value. - - VerifyVolume - Indicates if we were called from the verify path. We - do a few things different in this path. We don't update the Vcb in - the verify path. - -Return Value: - - BOOLEAN - TRUE if a valid primary volume descriptor found, FALSE - otherwise. - ---*/ - -{ - NTSTATUS Status; - ULONG ThisPass = 1; - BOOLEAN FoundVd = FALSE; - - ULONG BaseSector; - ULONG SectorOffset; - - PCDROM_TOC CdromToc; - - ULONG VolumeFlags; - - PAGED_CODE(); - - // - // If there are no data tracks, don't even bother hunting for descriptors. - // - // This explicitly breaks various non-BlueBook compliant CDs that scribble - // an ISO filesystem on media claiming only audio tracks. Since these - // disks can cause serious problems in some CDROM units, fail fast. I admit - // that it is possible that someone can still record the descriptors in the - // audio track, record a data track (but fail to record descriptors there) - // and still have the disk work. As this form of error worked in NT 4.0, and - // since these disks really do exist, I don't want to change them. - // - // If we wished to support all such media (we don't), it would be neccesary - // to clear this flag on finding ISO or HSG descriptors below. - // - - if (FlagOn(Vcb->VcbState, VCB_STATE_AUDIO_DISK)) { - - return FALSE; - } - - // - // We will make at most two passes through the volume descriptor sequence. - // - // On the first pass we will query for the last session. Using this - // as a starting offset we will attempt to mount the volume. On any failure - // we will go to the second pass and try without using any multi-session - // information. - // - // On the second pass we will start offset from sector zero. - // - - while (!FoundVd && (ThisPass <= 2)) { - - // - // If we aren't at pass 1 then we start at sector 0. Otherwise we - // try to look up the multi-session information. - // - - BaseSector = 0; - - if (ThisPass == 1) { - - CdromToc = NULL; - - // - // Check for whether this device supports XA and multi-session. - // - - try { - - // - // Allocate a buffer for the last session information. - // - - CdromToc = FsRtlAllocatePoolWithTag( CdPagedPool, - sizeof( CDROM_TOC ), - TAG_CDROM_TOC ); - - RtlZeroMemory( CdromToc, sizeof( CDROM_TOC )); - - // - // Query the last session information from the driver. - // - - Status = CdPerformDevIoCtrl( IrpContext, - IOCTL_CDROM_GET_LAST_SESSION, - Vcb->TargetDeviceObject, - CdromToc, - sizeof( CDROM_TOC ), - FALSE, - TRUE, - NULL ); - - // - // Raise an exception if there was an allocation failure. - // - - if (Status == STATUS_INSUFFICIENT_RESOURCES) { - - CdRaiseStatus( IrpContext, Status ); - } - - // - // We don't handle any errors yet. We will hit that below - // as we try to scan the disk. If we have last session information - // then modify the base sector. - // - - if (NT_SUCCESS( Status ) && - (CdromToc->FirstTrack != CdromToc->LastTrack)) { - - PCHAR Source, Dest; - ULONG Count; - - Count = 4; - - // - // The track address is BigEndian, we need to flip the bytes. - // - - Source = (PCHAR) &CdromToc->TrackData[0].Address[3];/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - Dest = (PCHAR) &BaseSector; /* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - - do { - - *Dest++ = *Source--; - - } while (--Count); - - // - // Now adjust the base sector by the block factor of the - // device. - // - - BaseSector /= BlockFactor; - - // - // Make this look like the second pass since we are only using the - // first session. No reason to retry on error. - // - - } else { - - ThisPass += 1; - } - - } finally { - - if (CdromToc != NULL) { CdFreePool( &CdromToc ); } - } - } - - // - // Compute the starting sector offset from the start of the session. - // - - SectorOffset = FIRST_VD_SECTOR; - - // - // Start by assuming we have neither Hsg or Iso volumes. - // - - VolumeFlags = 0; - - // - // Loop until either error encountered, primary volume descriptor is - // found or a terminal volume descriptor is found. - // - - while (TRUE) { - - // - // Attempt to read the desired sector. Exit directly if operation - // not completed. - // - // If this is pass 1 we will ignore errors in read sectors and just - // go to the next pass. - // - - if (!CdReadSectors( IrpContext, - LlBytesFromSectors( BaseSector + SectorOffset ), - SECTOR_SIZE, - (BOOLEAN) ((ThisPass == 1) || ReturnOnError), - RawIsoVd, - Vcb->TargetDeviceObject )) { - - break; - } - - // - // Check if either an ISO or HSG volume. - // - - if (RtlEqualMemory( CdIsoId, - CdRvdId( RawIsoVd, VCB_STATE_ISO ), - VOL_ID_LEN )) { - - SetFlag( VolumeFlags, VCB_STATE_ISO ); - - } else if (RtlEqualMemory( CdHsgId, - CdRvdId( RawIsoVd, VCB_STATE_HSG ), - VOL_ID_LEN )) { - - SetFlag( VolumeFlags, VCB_STATE_HSG ); - - // - // We have neither so break out of the loop. - // - - } else { - - break; - } - - // - // Break out if the version number is incorrect or this is - // a terminator. - // - - if ((CdRvdVersion( RawIsoVd, VolumeFlags ) != VERSION_1) || - (CdRvdDescType( RawIsoVd, VolumeFlags ) == VD_TERMINATOR)) { - - break; - } - - // - // If this is a primary volume descriptor then our search is over. - // - - if (CdRvdDescType( RawIsoVd, VolumeFlags ) == VD_PRIMARY) { - - // - // If we are not in the verify path then initialize the - // fields in the Vcb with basic information from this - // descriptor. - // - - if (!VerifyVolume) { - - // - // Set the flag for the volume type. - // - - SetFlag( Vcb->VcbState, VolumeFlags ); - - // - // Store the base sector and sector offset for the - // primary volume descriptor. - // - - Vcb->BaseSector = BaseSector; - Vcb->VdSectorOffset = SectorOffset; - Vcb->PrimaryVdSectorOffset = SectorOffset; - } - - FoundVd = TRUE; - break; - } - - // - // Indicate that we're at the next sector. - // - - SectorOffset += 1; - } - - ThisPass += 1; - } - - return FoundVd; -} - - -// -// Local support routine -// - -BOOLEAN -CdIsRemount ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - OUT PVCB *OldVcb - ) -/*++ - -Routine Description: - - This routine walks through the links of the Vcb chain in the global - data structure. The remount condition is met when the following - conditions are all met: - - If the new Vcb is a device only Mvcb and there is a previous - device only Mvcb. - - Otherwise following conditions must be matched. - - 1 - The 32 serial in the current VPB matches that in a previous - VPB. - - 2 - The volume label in the Vpb matches that in the previous - Vpb. - - 3 - The system pointer to the real device object in the current - VPB matches that in the same previous VPB. - - 4 - Finally the previous Vcb cannot be invalid or have a dismount - underway. - - If a VPB is found which matches these conditions, then the address of - the VCB for that VPB is returned via the pointer Vcb. - - Skip over the current Vcb. - -Arguments: - - Vcb - This is the Vcb we are checking for a remount. - - OldVcb - A pointer to the address to store the address for the Vcb - for the volume if this is a remount. (This is a pointer to - a pointer) - -Return Value: - - BOOLEAN - TRUE if this is in fact a remount, FALSE otherwise. - ---*/ - -{ - PLIST_ENTRY Link; - - PVPB Vpb = Vcb->Vpb; - PVPB OldVpb; - - BOOLEAN Remount = FALSE; - - PAGED_CODE(); - - // - // Check whether we are looking for a device only Mvcb. - // - - for (Link = CdData.VcbQueue.Flink; - Link != &CdData.VcbQueue; - Link = Link->Flink) { - - *OldVcb = CONTAINING_RECORD( Link, VCB, VcbLinks ); - - // - // Skip ourselves. - // - - if (Vcb == *OldVcb) { continue; } - - // - // Look at the Vpb and state of the previous Vcb. - // - - OldVpb = (*OldVcb)->Vpb; - - if ((OldVpb != Vpb) && - (OldVpb->RealDevice == Vpb->RealDevice) && - ((*OldVcb)->VcbCondition == VcbNotMounted)) { - - // - // If the current disk is a raw disk then it can match a previous music or - // raw disk. - // - - if (FlagOn( Vcb->VcbState, VCB_STATE_AUDIO_DISK)) { - - if (FlagOn( (*OldVcb)->VcbState, VCB_STATE_AUDIO_DISK )) { - - // - // If we have both TOC then fail the remount if the lengths - // are different or they don't match. - // - - if ((Vcb->TocLength != (*OldVcb)->TocLength) || - ((Vcb->TocLength != 0) && - !RtlEqualMemory( Vcb->CdromToc, - (*OldVcb)->CdromToc, - Vcb->TocLength ))) { - - continue; - } - - Remount = TRUE; - break; - } - - // - // The current disk is not a raw disk. Go ahead and compare - // serial numbers and volume label. - // - - } else if ((OldVpb->SerialNumber == Vpb->SerialNumber) && - (Vpb->VolumeLabelLength == OldVpb->VolumeLabelLength) && - (RtlEqualMemory( OldVpb->VolumeLabel, - Vpb->VolumeLabel, - Vpb->VolumeLabelLength ))) { - - // - // Remember the old mvcb. Then set the return value to - // TRUE and break. - // - - Remount = TRUE; - break; - } - } - } - - return Remount; -} - - -// -// Local support routine -// - -VOID -CdFindActiveVolDescriptor ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN OUT PCHAR RawIsoVd, - IN BOOLEAN VerifyVolume - ) - -/*++ - -Routine Description: - - This routine is called to search for a valid secondary volume descriptor that - we will support. Right now we only support Joliet escape sequences for - the secondary descriptor. - - If we don't find the secondary descriptor then we will reread the primary. - - This routine will update the serial number and volume label in the Vpb. - -Arguments: - - Vcb - This is the Vcb for the volume being mounted. - - RawIsoVd - Sector buffer used to read the volume descriptors from the disks, but - on input should contain the PVD (ISO) in the SECOND 'sector' of the - buffer. - - VerifyVolume - indicates we are being called by the verify path, and should - not modify the Vcb fields. - -Return Value: - - None - ---*/ - -{ - BOOLEAN FoundSecondaryVd = FALSE; - ULONG SectorOffset = FIRST_VD_SECTOR; - - ULONG Length; - - ULONG Index; - - PAGED_CODE(); - - // - // We only look for secondary volume descriptors on an Iso disk. - // - - if ((FlagOn( Vcb->VcbState, VCB_STATE_ISO) || VerifyVolume) && !CdNoJoliet) { - - // - // Scan the volume descriptors from the beginning looking for a valid - // secondary or a terminator. - // - - SectorOffset = FIRST_VD_SECTOR; - - while (TRUE) { - - // - // Read the next sector. We should never have an error in this - // path. - // - - CdReadSectors( IrpContext, - LlBytesFromSectors( Vcb->BaseSector + SectorOffset ), - SECTOR_SIZE, - FALSE, - RawIsoVd, - Vcb->TargetDeviceObject ); - - // - // Break out if the version number or standard Id is incorrect. - // Also break out if this is a terminator. - // - - if (!RtlEqualMemory( CdIsoId, CdRvdId( RawIsoVd, VCB_STATE_JOLIET ), VOL_ID_LEN ) || - (CdRvdVersion( RawIsoVd, VCB_STATE_JOLIET ) != VERSION_1) || - (CdRvdDescType( RawIsoVd, VCB_STATE_JOLIET ) == VD_TERMINATOR)) { - - break; - } - - // - // We have a match if this is a secondary descriptor with a matching - // escape sequence. - // - - if ((CdRvdDescType( RawIsoVd, VCB_STATE_JOLIET ) == VD_SECONDARY) && - (RtlEqualMemory( CdRvdEsc( RawIsoVd, VCB_STATE_JOLIET ), - CdJolietEscape[0], - ESC_SEQ_LEN ) || - RtlEqualMemory( CdRvdEsc( RawIsoVd, VCB_STATE_JOLIET ), - CdJolietEscape[1], - ESC_SEQ_LEN ) || - RtlEqualMemory( CdRvdEsc( RawIsoVd, VCB_STATE_JOLIET ), - CdJolietEscape[2], - ESC_SEQ_LEN ))) { - - if (!VerifyVolume) { - - // - // Update the Vcb with the new volume descriptor. - // - - ClearFlag( Vcb->VcbState, VCB_STATE_ISO ); - SetFlag( Vcb->VcbState, VCB_STATE_JOLIET ); - - Vcb->VdSectorOffset = SectorOffset; - } - - FoundSecondaryVd = TRUE; - break; - } - - // - // Otherwise move on to the next sector. - // - - SectorOffset += 1; - } - - // - // If we didn't find the secondary then recover the original volume - // descriptor stored in the second half of the RawIsoVd. - // - - if (!FoundSecondaryVd) { - - RtlCopyMemory( RawIsoVd, - Add2Ptr( RawIsoVd, SECTOR_SIZE, PVOID ), - SECTOR_SIZE ); - } - } - - // - // If we're in the verify path, our work is done, since we don't want - // to update any Vcb/Vpb values. - // - - if (VerifyVolume) { - - return; - } - - // - // Compute the serial number and volume label from the volume descriptor. - // - - Vcb->Vpb->SerialNumber = CdSerial32( RawIsoVd, SECTOR_SIZE ); - - // - // Make sure the CD label will fit in the Vpb. - // - - ASSERT( VOLUME_ID_LENGTH * sizeof( WCHAR ) <= MAXIMUM_VOLUME_LABEL_LENGTH ); - - // - // If this is not a Unicode label we must convert it to unicode. - // - - if (!FlagOn( Vcb->VcbState, VCB_STATE_JOLIET )) { - - // - // Convert the label to unicode. If we get any error then use a name - // length of zero. - // - - Vcb->Vpb->VolumeLabelLength = 0; - - if (NT_SUCCESS( RtlOemToUnicodeN( &Vcb->Vpb->VolumeLabel[0], - MAXIMUM_VOLUME_LABEL_LENGTH, - &Length, - (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ),/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - VOLUME_ID_LENGTH ))) { - - Vcb->Vpb->VolumeLabelLength = (USHORT) Length; - } - - // - // We need to convert from big-endian to little endian. - // - - } else { - - CdConvertBigToLittleEndian( IrpContext, - (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ),/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - VOLUME_ID_LENGTH, - (PCHAR) Vcb->Vpb->VolumeLabel ); - - Vcb->Vpb->VolumeLabelLength = VOLUME_ID_LENGTH * sizeof( WCHAR ); - } - - // - // Strip the trailing spaces or zeroes from the name. - // - - Index = Vcb->Vpb->VolumeLabelLength / sizeof( WCHAR ); - - while (Index > 0) { - - if ((Vcb->Vpb->VolumeLabel[ Index - 1 ] != L'\0') && - (Vcb->Vpb->VolumeLabel[ Index - 1 ] != L' ')) { - - break; - } - - Index -= 1; - } - - // - // Now set the final length for the name. - // - - Vcb->Vpb->VolumeLabelLength = (USHORT) (Index * sizeof( WCHAR )); -} - - - diff --git a/reactos/drivers/filesystems/cdfs_new/fspdisp.c b/reactos/drivers/filesystems/cdfs_new/fspdisp.c deleted file mode 100755 index b7c4e80b62a..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/fspdisp.c +++ /dev/null @@ -1,278 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - FspDisp.c - -Abstract: - - This module implements the main dispatch procedure/thread for the Cdfs - Fsp - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_FSPDISP) - - -VOID -CdFspDispatch ( - IN PIRP_CONTEXT IrpContext - ) - -/*++ - -Routine Description: - - This is the main FSP thread routine that is executed to receive - and dispatch IRP requests. Each FSP thread begins its execution here. - There is one thread created at system initialization time and subsequent - threads created as needed. - -Arguments: - - IrpContext - IrpContext for a request to process. - -Return Value: - - None - ---*/ - -{ - THREAD_CONTEXT ThreadContext; - NTSTATUS Status; - - PIRP Irp = IrpContext->Irp; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PVOLUME_DEVICE_OBJECT VolDo = NULL; - - // - // If this request has an associated volume device object, remember it. - // - - if (IrpSp->FileObject != NULL) { - - VolDo = CONTAINING_RECORD( IrpSp->DeviceObject, - VOLUME_DEVICE_OBJECT, - DeviceObject ); - } - - // - // Now case on the function code. For each major function code, - // either call the appropriate worker routine. This routine that - // we call is responsible for completing the IRP, and not us. - // That way the routine can complete the IRP and then continue - // post processing as required. For example, a read can be - // satisfied right away and then read can be done. - // - // We'll do all of the work within an exception handler that - // will be invoked if ever some underlying operation gets into - // trouble. - // - - while ( TRUE ) { - - // - // Set all the flags indicating we are in the Fsp. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FSP_FLAGS ); - - FsRtlEnterFileSystem(); - - CdSetThreadContext( IrpContext, &ThreadContext ); - - while (TRUE) { - - try { - - // - // Reinitialize for the next try at completing this - // request. - // - - Status = - IrpContext->ExceptionStatus = STATUS_SUCCESS; - - // - // Initialize the Io status field in the Irp. - // - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - - // - // Case on the major irp code. - // - - switch (IrpContext->MajorFunction) { - - case IRP_MJ_CREATE : - - CdCommonCreate( IrpContext, Irp ); - break; - - case IRP_MJ_CLOSE : - - ASSERT( FALSE ); - break; - - case IRP_MJ_READ : - - CdCommonRead( IrpContext, Irp ); - break; - - case IRP_MJ_QUERY_INFORMATION : - - CdCommonQueryInfo( IrpContext, Irp ); - break; - - case IRP_MJ_SET_INFORMATION : - - CdCommonSetInfo( IrpContext, Irp ); - break; - - case IRP_MJ_QUERY_VOLUME_INFORMATION : - - CdCommonQueryVolInfo( IrpContext, Irp ); - break; - - case IRP_MJ_DIRECTORY_CONTROL : - - CdCommonDirControl( IrpContext, Irp ); - break; - - case IRP_MJ_FILE_SYSTEM_CONTROL : - - CdCommonFsControl( IrpContext, Irp ); - break; - - case IRP_MJ_DEVICE_CONTROL : - - CdCommonDevControl( IrpContext, Irp ); - break; - - case IRP_MJ_LOCK_CONTROL : - - CdCommonLockControl( IrpContext, Irp ); - break; - - case IRP_MJ_CLEANUP : - - CdCommonCleanup( IrpContext, Irp ); - break; - - case IRP_MJ_PNP : - - ASSERT( FALSE ); - CdCommonPnp( IrpContext, Irp ); - break; - - default : - - Status = STATUS_INVALID_DEVICE_REQUEST; - CdCompleteRequest( IrpContext, Irp, Status ); - } - - } except( CdExceptionFilter( IrpContext, GetExceptionInformation() )) { - - Status = CdProcessException( IrpContext, Irp, GetExceptionCode() ); - } - - // - // Break out of the loop if we didn't get CANT_WAIT. - // - - if (Status != STATUS_CANT_WAIT) { break; } - - // - // We are retrying this request. Cleanup the IrpContext for the retry. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); - CdCleanupIrpContext( IrpContext, FALSE ); - } - - FsRtlExitFileSystem(); - - // - // If there are any entries on this volume's overflow queue, service - // them. - // - - if (VolDo != NULL) { - - KIRQL SavedIrql; - PVOID Entry = NULL; - - // - // We have a volume device object so see if there is any work - // left to do in its overflow queue. - // - - KeAcquireSpinLock( &VolDo->OverflowQueueSpinLock, &SavedIrql ); - - if (VolDo->OverflowQueueCount > 0) { - - // - // There is overflow work to do in this volume so we'll - // decrement the Overflow count, dequeue the IRP, and release - // the Event - // - - VolDo->OverflowQueueCount -= 1; - - Entry = RemoveHeadList( &VolDo->OverflowQueue ); - } - - KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql ); - - // - // There wasn't an entry, break out of the loop and return to - // the Ex Worker thread. - // - - if (Entry == NULL) { break; } - - // - // Extract the IrpContext , Irp, set wait to TRUE, and loop. - // - - IrpContext = CONTAINING_RECORD( Entry, - IRP_CONTEXT, - WorkQueueItem.List ); - - Irp = IrpContext->Irp; - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - continue; - } - - break; - } - - // - // Decrement the PostedRequestCount if there was a volume device object. - // - - if (VolDo) { - - InterlockedDecrement( &VolDo->PostedRequestCount ); - } - - return; -} - - - - diff --git a/reactos/drivers/filesystems/cdfs_new/lockctrl.c b/reactos/drivers/filesystems/cdfs_new/lockctrl.c deleted file mode 100755 index a986fb35ec3..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/lockctrl.c +++ /dev/null @@ -1,678 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - LockCtrl.c - -Abstract: - - This module implements the Lock Control routines for Cdfs called - by the Fsd/Fsp dispatch driver. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_LOCKCTRL) - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCommonLockControl) -#pragma alloc_text(PAGE, CdFastLock) -#pragma alloc_text(PAGE, CdFastUnlockAll) -#pragma alloc_text(PAGE, CdFastUnlockAllByKey) -#pragma alloc_text(PAGE, CdFastUnlockSingle) -#endif - - -NTSTATUS -CdCommonLockControl ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the common routine for Lock Control called by both the fsd and fsp - threads. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - TYPE_OF_OPEN TypeOfOpen; - PFCB Fcb; - PCCB Ccb; - - PAGED_CODE(); - - // - // Extract and decode the type of file object we're being asked to process - // - - TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ); - - // - // If the file is not a user file open then we reject the request - // as an invalid parameter - // - - if (TypeOfOpen != UserFileOpen) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - // - // We check whether we can proceed based on the state of the file oplocks. - // This call might post the irp for us. - // - - Status = FsRtlCheckOplock( &Fcb->Oplock, - Irp, - IrpContext, - (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - NULL ); - - // - // If we don't get success then the oplock package completed the request. - // - - if (Status != STATUS_SUCCESS) { - - return Status; - } - - // - // Verify the Fcb. - // - - CdVerifyFcbOperation( IrpContext, Fcb ); - - // - // If we don't have a file lock, then get one now. - // - - if (Fcb->FileLock == NULL) { CdCreateFileLock( IrpContext, Fcb, TRUE ); } - - // - // Now call the FsRtl routine to do the actual processing of the - // Lock request - // - - Status = FsRtlProcessFileLock( Fcb->FileLock, Irp, NULL ); - - // - // Set the flag indicating if Fast I/O is possible - // - - CdLockFcb( IrpContext, Fcb ); - Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); - CdUnlockFcb( IrpContext, Fcb ); - - // - // Complete the request. - // - - CdCompleteRequest( IrpContext, NULL, Status ); - return Status; -} - - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastLock ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - PEPROCESS ProcessId, - ULONG Key, - BOOLEAN FailImmediately, - BOOLEAN ExclusiveLock, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ) - -/*++ - -Routine Description: - - This is a call back routine for doing the fast lock call. - -Arguments: - - FileObject - Supplies the file object used in this operation - - FileOffset - Supplies the file offset used in this operation - - Length - Supplies the length used in this operation - - ProcessId - Supplies the process ID used in this operation - - Key - Supplies the key used in this operation - - FailImmediately - Indicates if the request should fail immediately - if the lock cannot be granted. - - ExclusiveLock - Indicates if this is a request for an exclusive or - shared lock - - IoStatus - Receives the Status if this operation is successful - -Return Value: - - BOOLEAN - TRUE if this operation completed and FALSE if caller - needs to take the long route. - ---*/ - -{ - BOOLEAN Results = FALSE; - - PFCB Fcb; - TYPE_OF_OPEN TypeOfOpen; - - PAGED_CODE(); - - ASSERT_FILE_OBJECT( FileObject ); - - IoStatus->Information = 0; - - // - // Decode the type of file object we're being asked to process and - // make sure that is is only a user file open. - // - - TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb ); - - if (TypeOfOpen != UserFileOpen) { - - IoStatus->Status = STATUS_INVALID_PARAMETER; - return TRUE; - } - - // - // Only deal with 'good' Fcb's. - // - - if (!CdVerifyFcbOperation( NULL, Fcb )) { - - return FALSE; - } - - FsRtlEnterFileSystem(); - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // We check whether we can proceed based on the state of the file oplocks. - // - - if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) { - - try_return( NOTHING ); - } - - // - // If we don't have a file lock, then get one now. - // - - if ((Fcb->FileLock == NULL) && !CdCreateFileLock( NULL, Fcb, FALSE )) { - - try_return( NOTHING ); - } - - // - // Now call the FsRtl routine to perform the lock request. - // - /* ReactOS Change: GCC "suggest parentheses around assignment used as truth value" */ - if ((Results = FsRtlFastLock( Fcb->FileLock, - FileObject, - FileOffset, - Length, - ProcessId, - Key, - FailImmediately, - ExclusiveLock, - IoStatus, - NULL, - FALSE ))) { - - // - // Set the flag indicating if Fast I/O is questionable. We - // only change this flag if the current state is possible. - // Retest again after synchronizing on the header. - // - - if (Fcb->IsFastIoPossible == FastIoIsPossible) { - - CdLockFcb( NULL, Fcb ); - Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); - CdUnlockFcb( NULL, Fcb ); - } - } - - try_exit: NOTHING; - } finally { - - FsRtlExitFileSystem(); - } - - return Results; -} - - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastUnlockSingle ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PLARGE_INTEGER Length, - PEPROCESS ProcessId, - ULONG Key, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ) - -/*++ - -Routine Description: - - This is a call back routine for doing the fast unlock single call. - -Arguments: - - FileObject - Supplies the file object used in this operation - - FileOffset - Supplies the file offset used in this operation - - Length - Supplies the length used in this operation - - ProcessId - Supplies the process ID used in this operation - - Key - Supplies the key used in this operation - - Status - Receives the Status if this operation is successful - -Return Value: - - BOOLEAN - TRUE if this operation completed and FALSE if caller - needs to take the long route. - ---*/ - -{ - BOOLEAN Results = FALSE; - TYPE_OF_OPEN TypeOfOpen; - PFCB Fcb; - - PAGED_CODE(); - - IoStatus->Information = 0; - - // - // Decode the type of file object we're being asked to process and - // make sure that is is only a user file open. - // - - TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb ); - - if (TypeOfOpen != UserFileOpen) { - - IoStatus->Status = STATUS_INVALID_PARAMETER; - return TRUE; - } - - // - // Only deal with 'good' Fcb's. - // - - if (!CdVerifyFcbOperation( NULL, Fcb )) { - - return FALSE; - } - - // - // If there is no lock then return immediately. - // - - if (Fcb->FileLock == NULL) { - - IoStatus->Status = STATUS_RANGE_NOT_LOCKED; - return TRUE; - } - - FsRtlEnterFileSystem(); - - try { - - // - // We check whether we can proceed based on the state of the file oplocks. - // - - if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) { - - try_return( NOTHING ); - } - - // - // If we don't have a file lock, then get one now. - // - - if ((Fcb->FileLock == NULL) && !CdCreateFileLock( NULL, Fcb, FALSE )) { - - try_return( NOTHING ); - } - - // - // Now call the FsRtl routine to do the actual processing of the - // Lock request. The call will always succeed. - // - - Results = TRUE; - IoStatus->Status = FsRtlFastUnlockSingle( Fcb->FileLock, - FileObject, - FileOffset, - Length, - ProcessId, - Key, - NULL, - FALSE ); - - // - // Set the flag indicating if Fast I/O is possible. We are - // only concerned if there are no longer any filelocks on this - // file. - // - - if (!FsRtlAreThereCurrentFileLocks( Fcb->FileLock ) && - (Fcb->IsFastIoPossible != FastIoIsPossible)) { - - CdLockFcb( IrpContext, Fcb ); - Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); - CdUnlockFcb( IrpContext, Fcb ); - } - - try_exit: NOTHING; - } finally { - - FsRtlExitFileSystem(); - } - - return Results; -} - - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastUnlockAll ( - IN PFILE_OBJECT FileObject, - PEPROCESS ProcessId, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ) - -/*++ - -Routine Description: - - This is a call back routine for doing the fast unlock all call. - -Arguments: - - FileObject - Supplies the file object used in this operation - - ProcessId - Supplies the process ID used in this operation - - Status - Receives the Status if this operation is successful - -Return Value: - - BOOLEAN - TRUE if this operation completed and FALSE if caller - needs to take the long route. - ---*/ - -{ - BOOLEAN Results = FALSE; - TYPE_OF_OPEN TypeOfOpen; - PFCB Fcb; - - PAGED_CODE(); - - IoStatus->Information = 0; - - // - // Decode the type of file object we're being asked to process and - // make sure that is is only a user file open. - // - - TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb ); - - if (TypeOfOpen != UserFileOpen) { - - IoStatus->Status = STATUS_INVALID_PARAMETER; - return TRUE; - } - - // - // Only deal with 'good' Fcb's. - // - - if (!CdVerifyFcbOperation( NULL, Fcb )) { - - return FALSE; - } - - // - // If there is no lock then return immediately. - // - - if (Fcb->FileLock == NULL) { - - IoStatus->Status = STATUS_RANGE_NOT_LOCKED; - return TRUE; - } - - FsRtlEnterFileSystem(); - - try { - - // - // We check whether we can proceed based on the state of the file oplocks. - // - - if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) { - - try_return( NOTHING ); - } - - // - // If we don't have a file lock, then get one now. - // - - if ((Fcb->FileLock == NULL) && !CdCreateFileLock( NULL, Fcb, FALSE )) { - - try_return( NOTHING ); - } - - // - // Now call the FsRtl routine to do the actual processing of the - // Lock request. The call will always succeed. - // - - Results = TRUE; - IoStatus->Status = FsRtlFastUnlockAll( Fcb->FileLock, - FileObject, - ProcessId, - NULL ); - - - // - // Set the flag indicating if Fast I/O is possible - // - - CdLockFcb( IrpContext, Fcb ); - Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); - CdUnlockFcb( IrpContext, Fcb ); - - try_exit: NOTHING; - } finally { - - FsRtlExitFileSystem(); - } - - return Results; -} - - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdFastUnlockAllByKey ( - IN PFILE_OBJECT FileObject, - PVOID ProcessId, - ULONG Key, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject - ) - -/*++ - -Routine Description: - - This is a call back routine for doing the fast unlock all by key call. - -Arguments: - - FileObject - Supplies the file object used in this operation - - ProcessId - Supplies the process ID used in this operation - - Key - Supplies the key used in this operation - - Status - Receives the Status if this operation is successful - -Return Value: - - BOOLEAN - TRUE if this operation completed and FALSE if caller - needs to take the long route. - ---*/ - -{ - BOOLEAN Results = FALSE; - TYPE_OF_OPEN TypeOfOpen; - PFCB Fcb; - - PAGED_CODE(); - - IoStatus->Information = 0; - - // - // Decode the type of file object we're being asked to process and - // make sure that is is only a user file open. - // - - TypeOfOpen = CdFastDecodeFileObject( FileObject, &Fcb ); - - if (TypeOfOpen != UserFileOpen) { - - IoStatus->Status = STATUS_INVALID_PARAMETER; - return TRUE; - } - - // - // Only deal with 'good' Fcb's. - // - - if (!CdVerifyFcbOperation( NULL, Fcb )) { - - return FALSE; - } - - // - // If there is no lock then return immediately. - // - - if (Fcb->FileLock == NULL) { - - IoStatus->Status = STATUS_RANGE_NOT_LOCKED; - return TRUE; - } - - FsRtlEnterFileSystem(); - - try { - - // - // We check whether we can proceed based on the state of the file oplocks. - // - - if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) { - - try_return( NOTHING ); - } - - // - // If we don't have a file lock, then get one now. - // - - if ((Fcb->FileLock == NULL) && !CdCreateFileLock( NULL, Fcb, FALSE )) { - - try_return( NOTHING ); - } - - // - // Now call the FsRtl routine to do the actual processing of the - // Lock request. The call will always succeed. - // - - Results = TRUE; - IoStatus->Status = FsRtlFastUnlockAllByKey( Fcb->FileLock, - FileObject, - ProcessId, - Key, - NULL ); - - - // - // Set the flag indicating if Fast I/O is possible - // - - CdLockFcb( IrpContext, Fcb ); - Fcb->IsFastIoPossible = CdIsFastIoPossible( Fcb ); - CdUnlockFcb( IrpContext, Fcb ); - - try_exit: NOTHING; - } finally { - - FsRtlExitFileSystem(); - } - - return Results; -} - - - diff --git a/reactos/drivers/filesystems/cdfs_new/namesup.c b/reactos/drivers/filesystems/cdfs_new/namesup.c deleted file mode 100755 index 9d687ddfda5..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/namesup.c +++ /dev/null @@ -1,1044 +0,0 @@ -/*++ - -Copyright (c) 1991-2000 Microsoft Corporation - -Module Name: - - NameSup.c - -Abstract: - - This module implements the Cdfs Name support routines - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_NAMESUP) - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdConvertBigToLittleEndian) -#pragma alloc_text(PAGE, CdConvertNameToCdName) -#pragma alloc_text(PAGE, CdDissectName) -#pragma alloc_text(PAGE, CdGenerate8dot3Name) -#pragma alloc_text(PAGE, CdFullCompareNames) -#pragma alloc_text(PAGE, CdIs8dot3Name) -#pragma alloc_text(PAGE, CdIsNameInExpression) -#pragma alloc_text(PAGE, CdShortNameDirentOffset) -#pragma alloc_text(PAGE, CdUpcaseName) -#endif - - -VOID -CdConvertNameToCdName ( - IN PIRP_CONTEXT IrpContext, - IN OUT PCD_NAME CdName - ) - -/*++ - -Routine Description: - - This routine is called to convert a string of bytes into a CdName. - - The full name is already in the CdName structure in the FileName field. - We split this into the filename and version strings. - -Arguments: - - CdName - Pointer to CdName structure to update. - -Return Value: - - None. - ---*/ - -{ - ULONG NameLength = 0; - PWCHAR CurrentCharacter = CdName->FileName.Buffer; - - PAGED_CODE(); - - // - // Look for a separator character. - // - - while ((NameLength < CdName->FileName.Length) && - (*CurrentCharacter != L';')) { - - CurrentCharacter += 1; - NameLength += 2; - } - - // - // If there is at least one more character after a possible separator then it - // and all following characters are part of the version string. - // - - CdName->VersionString.Length = 0; - if (NameLength + sizeof( WCHAR ) < CdName->FileName.Length) { - - CdName->VersionString.MaximumLength = - CdName->VersionString.Length = (USHORT) (CdName->FileName.Length - NameLength - sizeof( WCHAR )); - CdName->VersionString.Buffer = Add2Ptr( CdName->FileName.Buffer, - NameLength + sizeof( WCHAR ), - PWCHAR ); - } - - // - // Now update the filename portion of the name. - // - - CdName->FileName.Length = (USHORT) NameLength; - - return; -} - - -VOID -CdConvertBigToLittleEndian ( - IN PIRP_CONTEXT IrpContext, - IN PCHAR BigEndian, - IN ULONG ByteCount, - OUT PCHAR LittleEndian - ) - -/*++ - -Routine Description: - - This routine is called to convert a unicode string in big endian to - little endian. We start by copying all of the source bytes except - the first. This will put the low order bytes in the correct position. - We then copy each high order byte in its correct position. - -Arguments: - - BigEndian - Pointer to the string of big endian characters. - - ByteCount - Number of unicode characters in this string. - - LittleEndian - Pointer to array to store the little endian characters. - -Return Value: - - None. - ---*/ - -{ - ULONG RemainingByteCount = ByteCount; - - PCHAR Source = BigEndian; - PCHAR Destination = LittleEndian; - - PAGED_CODE(); - - // - // If the byte count isn't an even number then the disk is corrupt. - // - - if (FlagOn( ByteCount, 1 )) { - - CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); - } - - // - // Start by copy the low-order bytes into the correct position. Do - // this by skipping the first byte in the BigEndian string. - // - - RtlCopyMemory( Destination, - Source + 1, - RemainingByteCount - 1 ); - - // - // Now move the high-order bytes into position. - // - - Destination += 1; - - while (RemainingByteCount != 0) { - - *Destination = *Source; - - Source += 2; - Destination += 2; - - RemainingByteCount -= 2; - } - - return; -} - - -VOID -CdUpcaseName ( - IN PIRP_CONTEXT IrpContext, - IN PCD_NAME Name, - IN OUT PCD_NAME UpcaseName - ) - -/*++ - -Routine Description: - - This routine is called to upcase a CdName structure. We will do both - the filename and version strings. - -Arguments: - - Name - This is the mixed case version of the name. - - UpcaseName - This is the destination for the upcase operation. - -Return Value: - - None. This routine will raise all errors. - ---*/ - -{ - NTSTATUS Status; - //PVOID NewBuffer; /* ReactOS Change: GCC Uninitialized variable */ - - PAGED_CODE(); - - // - // If the name structures are different then initialize the different components. - // - - if (Name != UpcaseName) { - - // - // Initialize the version string portion of the name. - // - - UpcaseName->VersionString.Length = 0; - - if (Name->VersionString.Length != 0) { - - UpcaseName->VersionString.MaximumLength = - UpcaseName->VersionString.Length = Name->VersionString.Length; - - // - // Initially set the buffer to point to where we need to insert - // the separator. - // - - UpcaseName->VersionString.Buffer = Add2Ptr( UpcaseName->FileName.Buffer, - Name->FileName.Length, - PWCHAR ); - - // - // We are currently pointing to the location to store the separator. - // Store the ';' and then move to the next character to - // copy the data. - // - - *(UpcaseName->VersionString.Buffer) = L';'; - - UpcaseName->VersionString.Buffer += 1; - } - } - - // - // Upcase the string using the correct upcase routine. - // - - Status = RtlUpcaseUnicodeString( &UpcaseName->FileName, - &Name->FileName, - FALSE ); - - // - // This should never fail. - // - - ASSERT( Status == STATUS_SUCCESS ); - - if (Name->VersionString.Length != 0) { - - Status = RtlUpcaseUnicodeString( &UpcaseName->VersionString, - &Name->VersionString, - FALSE ); - - // - // This should never fail. - // - - ASSERT( Status == STATUS_SUCCESS ); - } - - return; -} - - -VOID -CdDissectName ( - IN PIRP_CONTEXT IrpContext, - IN OUT PUNICODE_STRING RemainingName, - OUT PUNICODE_STRING FinalName - ) - -/*++ - -Routine Description: - - This routine is called to strip off leading components of the name strings. We search - for either the end of the string or separating characters. The input remaining - name strings should have neither a trailing or leading backslash. - -Arguments: - - RemainingName - Remaining name. - - FinalName - Location to store next component of name. - -Return Value: - - None. - ---*/ - -{ - ULONG NameLength; - PWCHAR NextWchar; - - PAGED_CODE(); - - // - // Find the offset of the next component separators. - // - - for (NameLength = 0, NextWchar = RemainingName->Buffer; - (NameLength < RemainingName->Length) && (*NextWchar != L'\\'); - NameLength += sizeof( WCHAR) , NextWchar += 1); - - // - // Adjust all the strings by this amount. - // - - FinalName->Buffer = RemainingName->Buffer; - - FinalName->MaximumLength = FinalName->Length = (USHORT) NameLength; - - // - // If this is the last component then set the RemainingName lengths to zero. - // - - if (NameLength == RemainingName->Length) { - - RemainingName->Length = 0; - - // - // Otherwise we adjust the string by this amount plus the separating character. - // - - } else { - - RemainingName->MaximumLength -= (USHORT) (NameLength + sizeof( WCHAR )); - RemainingName->Length -= (USHORT) (NameLength + sizeof( WCHAR )); - RemainingName->Buffer = Add2Ptr( RemainingName->Buffer, - NameLength + sizeof( WCHAR ), - PWCHAR ); - } - - return; -} - - -BOOLEAN -CdIs8dot3Name ( - IN PIRP_CONTEXT IrpContext, - IN UNICODE_STRING FileName - ) - -/*++ - -Routine Description: - - This routine checks if the name follows the 8.3 name conventions. We check for - the name length and whether the characters are valid. - -Arguments: - - FileName - String of bytes containing the name. - -Return Value: - - BOOLEAN - TRUE if this name is a legal 8.3 name, FALSE otherwise. - ---*/ - -{ - CHAR DbcsNameBuffer[ BYTE_COUNT_8_DOT_3 ]; - STRING DbcsName; - - PWCHAR NextWchar; - ULONG Count; - - ULONG DotCount = 0; - BOOLEAN LastCharDot = FALSE; - - PAGED_CODE(); - - // - // The length must be less than 24 bytes. - // - - ASSERT( FileName.Length != 0 ); - if (FileName.Length > BYTE_COUNT_8_DOT_3) { - - return FALSE; - } - - // - // Walk though and check for a space character. - // - - NextWchar = FileName.Buffer; - Count = 0; - - do { - - // - // No spaces allowed. - // - - if (*NextWchar == L' ') { return FALSE; } - - if (*NextWchar == L'.') { - - // - // Not an 8.3 name if more than 1 dot or more than 8 characters - // remaining. (It is legal for the dot to be in the ninth - // position) - // - - if ((DotCount > 0) || - (Count > 8 * sizeof( WCHAR ))) { - - return FALSE; - } - - DotCount += 1; - LastCharDot = TRUE; - - } else { - - LastCharDot = FALSE; - } - - Count += 2; - NextWchar += 1; - - } while (Count < FileName.Length); - - // - // Go ahead and truncate the dot if at the end. - // - - if (LastCharDot) { - - FileName.Length -= sizeof( WCHAR ); - } - - // - // Create an Oem name to use to check for a valid short name. - // - - DbcsName.MaximumLength = BYTE_COUNT_8_DOT_3; - DbcsName.Buffer = DbcsNameBuffer; - - if (!NT_SUCCESS( RtlUnicodeStringToCountedOemString( &DbcsName, - &FileName, - FALSE ))) { - - return FALSE; - } - - // - // We have now initialized the Oem string. Call the FsRtl package to check for a - // valid FAT name. - // - - return FsRtlIsFatDbcsLegal( DbcsName, FALSE, FALSE, FALSE ); -} - - -VOID -CdGenerate8dot3Name ( - IN PIRP_CONTEXT IrpContext, - IN PUNICODE_STRING FileName, - IN ULONG DirentOffset, - OUT PWCHAR ShortFileName, - OUT PUSHORT ShortByteCount - ) - -/*++ - -Routine Description: - - This routine is called to generate a short name from the given long name. We will - generate a short name from the given long name. - - We go through the following steps to make this conversion. - - 1 - Generate the generic short name. This will also be in unicode format. - - 2 - Build the string representation of the dirent offset. - - 3 - Build the biased short name string by combining the generic short name with - the dirent offset string. - - 4 - Copy the final unicode string back to our caller's buffer. - -Arguments: - - FileName - String of bytes containing the name. - - DirentOffset - Offset in the directory for this filename. We incorporate the offset into - the short name by dividing this by 32 and prepending a tilde character to the - digit character. We then append this to the base of the generated short name. - - ShortFileName - Pointer to the buffer to store the short name into. - - ShortByteCount - Address to store the number of bytes in the short name. - -Return Value: - - None. - ---*/ - -{ - NTSTATUS Status; - UNICODE_STRING ShortName; - UNICODE_STRING BiasedShortName; - WCHAR ShortNameBuffer[ BYTE_COUNT_8_DOT_3 / sizeof( WCHAR ) ]; - WCHAR BiasedShortNameBuffer[ BYTE_COUNT_8_DOT_3 / sizeof( WCHAR ) ]; - - GENERATE_NAME_CONTEXT NameContext; - - ULONG BiasedDirentOffset; - - ULONG MaximumBaseBytes; - ULONG BaseNameOffset; - - PWCHAR NextWchar; - WCHAR ThisWchar; - USHORT Length; - - BOOLEAN FoundTilde = FALSE; - - OEM_STRING OemName; - USHORT OemNameOffset = 0; - BOOLEAN OverflowBuffer = FALSE; - - PAGED_CODE(); - - // - // Initialize the short string to use the input buffer. - // - - ShortName.Buffer = ShortNameBuffer; - ShortName.MaximumLength = BYTE_COUNT_8_DOT_3; - - // - // Initialize the name context. - // - - RtlZeroMemory( &NameContext, sizeof( GENERATE_NAME_CONTEXT )); - - // - // We now have the unicode name for the input string. Go ahead and generate - // the short name. - // - - RtlGenerate8dot3Name( FileName, TRUE, &NameContext, &ShortName ); - - // - // We now have the generic short name. We want incorporate the dirent offset - // into the name in order to reduce the chance of name conflicts. We will use - // a tilde character followed by a character representation of the dirent offset. - // This will be the hexadecimal representation of the dirent offset in the directory. - // It is actuall this offset divided by 32 since we don't need the full - // granularity. - // - - BiasedDirentOffset = DirentOffset >> SHORT_NAME_SHIFT; - - // - // Point to a local buffer to store the offset string. We start - // at the end of the buffer and work backwards. - // - - NextWchar = Add2Ptr( BiasedShortNameBuffer, - BYTE_COUNT_8_DOT_3, - PWCHAR ); - - BiasedShortName.MaximumLength = BYTE_COUNT_8_DOT_3; - - // - // Generate an OEM version of the string so that we can check for double - // byte characters. - // - - Status = RtlUnicodeStringToOemString(&OemName, &ShortName, TRUE); - - if (!NT_SUCCESS( Status )) { - - CdRaiseStatus( IrpContext, Status ); - } - - Length = 0; - - // - // Now add the characters for the dirent offset. We need to start - // from the least significant digit and work backwards. - // - - do { - - NextWchar -= 1; - - ThisWchar = (WCHAR) (BiasedDirentOffset & 0x0000000f); - - // - // Store in the next character. Bias against either '0' or 'A' - // - - if (ThisWchar <= 9) { - - *NextWchar = ThisWchar + L'0'; - - } else { - - *NextWchar = ThisWchar + L'A' - 0xA; - } - - Length += sizeof( WCHAR ); - - // - // Shift out the low 4 bits of the offset. - // - - BiasedDirentOffset >>= 4; - - } while (BiasedDirentOffset != 0); - - // - // Now store in the tilde character. - // - - NextWchar -= 1; - *NextWchar = L'~'; - Length += sizeof( WCHAR ); - - // - // Set the length of this string. - // - - BiasedShortName.Length = Length; - BiasedShortName.Buffer = NextWchar; - - // - // Figure out the maximum number of characters we can copy of the base - // name. We subract the number of characters in the dirent string from 8. - // We will copy this many characters or stop when we reach a '.' character - // or a '~' character in the name. - // - - MaximumBaseBytes = 16 - Length; - - BaseNameOffset = 0; - - // - // Keep copying from the base name until we hit a '.', '~' or the end of - // the short name. - // - - NextWchar = ShortFileName; - Length = 0; - - while ((BaseNameOffset < ShortName.Length) && - (ShortName.Buffer[BaseNameOffset / 2] != L'.')) { - - // - // Remember if we found a tilde character in the short name, - // so we don't copy it or anything following it. - // - - if (ShortName.Buffer[BaseNameOffset / 2] == L'~') { - - FoundTilde = TRUE; - } - - // - // We need to consider the DBCS code page, because Unicode characters - // may use 2 bytes as DBCS characters. - // - - if (FsRtlIsLeadDbcsCharacter(OemName.Buffer[OemNameOffset])) { - - OemNameOffset += 2; - } - else { - - OemNameOffset++; - } - - if ((OemNameOffset + (BiasedShortName.Length / sizeof(WCHAR))) > 8) { - - OverflowBuffer = TRUE; - } - - // - // Only copy the bytes if we still have space for the dirent string. - // - - if (!FoundTilde && !OverflowBuffer && (BaseNameOffset < MaximumBaseBytes)) { - - *NextWchar = ShortName.Buffer[BaseNameOffset / 2]; - Length += sizeof( WCHAR ); - NextWchar += 1; - } - - BaseNameOffset += 2; - } - - RtlFreeOemString(&OemName); - - // - // Now copy the dirent string into the biased name buffer. - // - - RtlCopyMemory( NextWchar, - BiasedShortName.Buffer, - BiasedShortName.Length ); - - Length += BiasedShortName.Length; - NextWchar += (BiasedShortName.Length / sizeof( WCHAR )); - - // - // Now copy any remaining bytes over to the biased short name. - // - - if (BaseNameOffset != ShortName.Length) { - - RtlCopyMemory( NextWchar, - &ShortName.Buffer[BaseNameOffset / 2], - ShortName.Length - BaseNameOffset ); - - Length += (ShortName.Length - (USHORT) BaseNameOffset); - } - - // - // The final short name is stored in the user's buffer. - // - - *ShortByteCount = Length; - - return; -} - - -BOOLEAN -CdIsNameInExpression ( - IN PIRP_CONTEXT IrpContext, - IN PCD_NAME CurrentName, - IN PCD_NAME SearchExpression, - IN ULONG WildcardFlags, - IN BOOLEAN CheckVersion - ) - -/*++ - -Routine Description: - - This routine will compare two CdName strings. We assume that if this - is to be a case-insensitive search then they are already upcased. - - We compare the filename portions of the name and if they match we - compare the version strings if requested. - -Arguments: - - CurrentName - Filename from the disk. - - SearchExpression - Filename expression to use for match. - - WildcardFlags - Flags field which indicates which parts of the - search expression might have wildcards. These flags are the - same as in the Ccb flags field. - - CheckVersion - Indicates whether we should check both the name and the - version strings or just the name. - -Return Value: - - BOOLEAN - TRUE if the expressions match, FALSE otherwise. - ---*/ - -{ - BOOLEAN Match = TRUE; - PAGED_CODE(); - - // - // If there are wildcards in the expression then we call the - // appropriate FsRtlRoutine. - // - - if (FlagOn( WildcardFlags, CCB_FLAG_ENUM_NAME_EXP_HAS_WILD )) { - - Match = FsRtlIsNameInExpression( &SearchExpression->FileName, - &CurrentName->FileName, - FALSE, - NULL ); - - // - // Otherwise do a direct memory comparison for the name string. - // - - } else { - - if ((CurrentName->FileName.Length != SearchExpression->FileName.Length) || - (!RtlEqualMemory( CurrentName->FileName.Buffer, - SearchExpression->FileName.Buffer, - CurrentName->FileName.Length ))) { - - Match = FALSE; - } - } - - // - // Check the version numbers if requested by the user and we have a - // match on the name and the version number is present. - // - - if (Match && CheckVersion && SearchExpression->VersionString.Length && - !FlagOn( WildcardFlags, CCB_FLAG_ENUM_VERSION_MATCH_ALL )) { - - // - // If there are wildcards in the expression then call the - // appropriate search expression. - // - - if (FlagOn( WildcardFlags, CCB_FLAG_ENUM_VERSION_EXP_HAS_WILD )) { - - Match = FsRtlIsNameInExpression( &SearchExpression->VersionString, - &CurrentName->VersionString, - FALSE, - NULL ); - - // - // Otherwise do a direct memory comparison for the name string. - // - - } else { - - if ((CurrentName->VersionString.Length != SearchExpression->VersionString.Length) || - (!RtlEqualMemory( CurrentName->VersionString.Buffer, - SearchExpression->VersionString.Buffer, - CurrentName->VersionString.Length ))) { - - Match = FALSE; - } - } - } - - return Match; -} - - -ULONG -CdShortNameDirentOffset ( - IN PIRP_CONTEXT IrpContext, - IN PUNICODE_STRING Name - ) - -/*++ - -Routine Description: - - This routine is called to examine a name to see if the dirent offset string is contained. - This consists of a tilde character followed by the offset represented as a hexadecimal - characters. We don't do any other checks to see if this is a short name. We - catch that later outside this routine. - -Arguments: - - Name - This is the CdName to examine. - -Return Value: - - ULONG - MAXULONG if there is no valid dirent offset string embedded, otherwise the - convert the value to numeric form. - ---*/ - -{ - ULONG ResultOffset = MAXULONG; - ULONG RemainingByteCount = Name->Length; - - BOOLEAN FoundTilde = FALSE; - - PWCHAR NextWchar; - - PAGED_CODE(); - - // - // Walk through the name until we either reach the end of the name - // or find a tilde character. - // - - for (NextWchar = Name->Buffer; - RemainingByteCount != 0; - NextWchar += 1, RemainingByteCount -= sizeof( WCHAR )) { - - // - // Check if this is a dot. Stop constructing any string if - // we found a dot. - // - - if (*NextWchar == L'.') { - - break; - } - - // - // If we already found a tilde then check this character as a - // valid character. It must be a digit or A to F. - // - - if (FoundTilde) { - - if ((*NextWchar < L'0') || - (*NextWchar > L'F') || - ((*NextWchar > L'9') && (*NextWchar < 'A'))) { - - ResultOffset = MAXULONG; - break; - } - - // - // Shift the result by 4 bits and add in this new character. - // - - ResultOffset <<= 4; - - if (*NextWchar < L'A') { - - ResultOffset += *NextWchar - L'0'; - - } else { - - ResultOffset += (*NextWchar - L'A') + 10; - } - - continue; - } - - // - // If this is a tilde then start building the dirent string. - // - - if (*NextWchar == L'~') { - - FoundTilde = TRUE; - ResultOffset = 0; - } - } - - return ResultOffset; -} - - -// -// Local support routine -// - -FSRTL_COMPARISON_RESULT -CdFullCompareNames ( - IN PIRP_CONTEXT IrpContext, - IN PUNICODE_STRING NameA, - IN PUNICODE_STRING NameB - ) - -/*++ - -Routine Description: - - This function compares two names as fast as possible. Note that since - this comparison is case sensitive we can do a direct memory comparison. - -Arguments: - - NameA & NameB - The names to compare. - -Return Value: - - COMPARISON - returns - - LessThan if NameA < NameB lexicalgraphically, - GreaterThan if NameA > NameB lexicalgraphically, - EqualTo if NameA is equal to NameB - ---*/ - -{ - SIZE_T i; - ULONG MinLength = NameA->Length; - FSRTL_COMPARISON_RESULT Result = LessThan; - - PAGED_CODE(); - - // - // Figure out the minimum of the two lengths - // - - if (NameA->Length > NameB->Length) { - - MinLength = NameB->Length; - Result = GreaterThan; - - } else if (NameA->Length == NameB->Length) { - - Result = EqualTo; - } - - // - // Loop through looking at all of the characters in both strings - // testing for equalilty, less than, and greater than - // - - i = RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinLength ); - - if (i < MinLength) { - - // - // We know the offset of the first character which is different. - // - - return ((NameA->Buffer[ i / 2 ] < NameB->Buffer[ i / 2 ]) ? - LessThan : - GreaterThan); - } - - // - // The names match up to the length of the shorter string. - // The shorter string lexically appears first. - // - - return Result; -} - - - diff --git a/reactos/drivers/filesystems/cdfs_new/nodetype.h b/reactos/drivers/filesystems/cdfs_new/nodetype.h deleted file mode 100755 index 67939548159..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/nodetype.h +++ /dev/null @@ -1,105 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - NodeType.h - -Abstract: - - This module defines all of the node type codes used in this development - shell. Every major data structure in the file system is assigned a node - type code that is. This code is the first CSHORT in the structure and is - followed by a CSHORT containing the size, in bytes, of the structure. - - ---*/ - -#ifndef _CDNODETYPE_ -#define _CDNODETYPE_ - -typedef CSHORT NODE_TYPE_CODE; -typedef NODE_TYPE_CODE *PNODE_TYPE_CODE; - -#define NTC_UNDEFINED ((NODE_TYPE_CODE)0x0000) - -#define CDFS_NTC_DATA_HEADER ((NODE_TYPE_CODE)0x0301) -#define CDFS_NTC_VCB ((NODE_TYPE_CODE)0x0302) -#define CDFS_NTC_FCB_PATH_TABLE ((NODE_TYPE_CODE)0x0303) -#define CDFS_NTC_FCB_INDEX ((NODE_TYPE_CODE)0x0304) -#define CDFS_NTC_FCB_DATA ((NODE_TYPE_CODE)0x0305) -#define CDFS_NTC_FCB_NONPAGED ((NODE_TYPE_CODE)0x0306) -#define CDFS_NTC_CCB ((NODE_TYPE_CODE)0x0307) -#define CDFS_NTC_IRP_CONTEXT ((NODE_TYPE_CODE)0x0308) -#define CDFS_NTC_IRP_CONTEXT_LITE ((NODE_TYPE_CODE)0x0309) - -typedef CSHORT NODE_BYTE_SIZE; - -// -// So all records start with -// -// typedef struct _RECORD_NAME { -// NODE_TYPE_CODE NodeTypeCode; -// NODE_BYTE_SIZE NodeByteSize; -// : -// } RECORD_NAME; -// typedef RECORD_NAME *PRECORD_NAME; -// - -#ifndef NodeType -#define NodeType(P) ((P) != NULL ? (*((PNODE_TYPE_CODE)(P))) : NTC_UNDEFINED) -#endif -#ifndef SafeNodeType -#define SafeNodeType(Ptr) (*((PNODE_TYPE_CODE)(Ptr))) -#endif - -// -// The following definitions are used to generate meaningful blue bugcheck -// screens. On a bugcheck the file system can output 4 ulongs of useful -// information. The first ulong will have encoded in it a source file id -// (in the high word) and the line number of the bugcheck (in the low word). -// The other values can be whatever the caller of the bugcheck routine deems -// necessary. -// -// Each individual file that calls bugcheck needs to have defined at the -// start of the file a constant called BugCheckFileId with one of the -// CDFS_BUG_CHECK_ values defined below and then use CdBugCheck to bugcheck -// the system. -// - -#define CDFS_BUG_CHECK_ACCHKSUP (0x00010000) -#define CDFS_BUG_CHECK_ALLOCSUP (0x00020000) -#define CDFS_BUG_CHECK_CACHESUP (0x00030000) -#define CDFS_BUG_CHECK_CDDATA (0x00040000) -#define CDFS_BUG_CHECK_CDINIT (0x00050000) -#define CDFS_BUG_CHECK_CLEANUP (0x00060000) -#define CDFS_BUG_CHECK_CLOSE (0x00070000) -#define CDFS_BUG_CHECK_CREATE (0x00080000) -#define CDFS_BUG_CHECK_DEVCTRL (0x00090000) -#define CDFS_BUG_CHECK_DEVIOSUP (0x000a0000) -#define CDFS_BUG_CHECK_DIRCTRL (0x000b0000) -#define CDFS_BUG_CHECK_DIRSUP (0x000c0000) -#define CDFS_BUG_CHECK_FILEINFO (0x000d0000) -#define CDFS_BUG_CHECK_FILOBSUP (0x000e0000) -#define CDFS_BUG_CHECK_FSCTRL (0x000f0000) -#define CDFS_BUG_CHECK_FSPDISP (0x00100000) -#define CDFS_BUG_CHECK_LOCKCTRL (0x00110000) -#define CDFS_BUG_CHECK_NAMESUP (0x00120000) -#define CDFS_BUG_CHECK_PATHSUP (0x00130000) -#define CDFS_BUG_CHECK_PNP (0x00140000) -#define CDFS_BUG_CHECK_PREFXSUP (0x00150000) -#define CDFS_BUG_CHECK_READ (0x00160000) -#define CDFS_BUG_CHECK_RESRCSUP (0x00170000) -#define CDFS_BUG_CHECK_STRUCSUP (0x00180000) -#define CDFS_BUG_CHECK_TIMESUP (0x00190000) -#define CDFS_BUG_CHECK_VERFYSUP (0x001a0000) -#define CDFS_BUG_CHECK_VOLINFO (0x001b0000) -#define CDFS_BUG_CHECK_WORKQUE (0x001c0000) - -/* ReactOS Change: Need to add to reactos.mc */ -#define CDFS_FILE_SYSTEM ((ULONG)0x00000026L) -#define CdBugCheck(A,B,C) { KeBugCheckEx(CDFS_FILE_SYSTEM, BugCheckFileId | __LINE__, A, B, C ); } - -#endif // _NODETYPE_ - diff --git a/reactos/drivers/filesystems/cdfs_new/pathsup.c b/reactos/drivers/filesystems/cdfs_new/pathsup.c deleted file mode 100755 index f9484d25d00..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/pathsup.c +++ /dev/null @@ -1,997 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - PathSup.c - -Abstract: - - This module implements the Path Table support routines for Cdfs. - - The path table on a CDROM is a condensed summary of the entire - directory structure. It is stored on a number of contiguous sectors - on the disk. Each directory on the disk has an entry in the path - table. The entries are aligned on USHORT boundaries and MAY span - sector boundaries. The entries are stored as a breadth-first search. - - The first entry in the table contains the entry for the root. The - next entries will consist of the contents of the root directory. The - next entries will consist of the all the directories at the next level - of the tree. The children of a given directory will be grouped together. - - The directories are assigned ordinal numbers based on their position in - the path table. The root dirctory is assigned ordinal value 1. - - Path table sectors: - - Ordinal 1 2 3 4 5 6 - +-----------+ - | Spanning | - | Sectors | - +----------------------------+ +------------------------+ - | | | | | | | | | - DirName | \ | a | b |c| | c | d | e | - | | | | | | | | | - Parent #| 1 | 1 | 1 | | | 2 | 2 | 3 | - +----------------------------+ +------------------------+ - - Directory Tree: - - \ (root) - - / \ - / \ - a b - - / \ \ - / \ \ - c d e - - Path Table Entries: - - - Position scan at known offset in the path table. Path Entry at - this offset must exist and is known to be valid. Used when - scanning for the children of a given directory. - - - Position scan at known offset in the path table. Path Entry is - known to start at this location but the bounds must be checked - for validity. - - - Move to next path entry in the table. - - - Update a common path entry structure with the details of the - on-disk structure. This is used to smooth out the differences - in the on-disk structures. - - - Update the filename in the in-memory path entry with the bytes - off the disk. For Joliet disks we will have - to convert to little endian. We assume that directories - don't have version numbers. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_PATHSUP) - -// -// Local macros -// - -// -// PRAW_PATH_ENTRY -// CdRawPathEntry ( -// IN PIRP_CONTEXT IrpContext, -// IN PPATH_ENUM_CONTEXT PathContext -// ); -// - -#define CdRawPathEntry(IC, PC) \ - Add2Ptr( (PC)->Data, (PC)->DataOffset, PRAW_PATH_ENTRY ) - -// -// Local support routines -// - -VOID -CdMapPathTableBlock ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG BaseOffset, - IN OUT PPATH_ENUM_CONTEXT PathContext - ); - -BOOLEAN -CdUpdatePathEntryFromRawPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN ULONG Ordinal, - IN BOOLEAN VerifyBounds, - IN PPATH_ENUM_CONTEXT PathContext, - OUT PPATH_ENTRY PathEntry - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdFindPathEntry) -#pragma alloc_text(PAGE, CdLookupPathEntry) -#pragma alloc_text(PAGE, CdLookupNextPathEntry) -#pragma alloc_text(PAGE, CdMapPathTableBlock) -#pragma alloc_text(PAGE, CdUpdatePathEntryFromRawPathEntry) -#pragma alloc_text(PAGE, CdUpdatePathEntryName) -#endif - - -VOID -CdLookupPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN ULONG PathEntryOffset, - IN ULONG Ordinal, - IN BOOLEAN VerifyBounds, - IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry - ) - -/*++ - -Routine Description: - - This routine is called to initiate a walk through a path table. We are - looking for a path table entry at location PathEntryOffset. - -Arguments: - - PathEntryOffset - This is our target point in the Path Table. We know that - a path entry must begin at this point although we may have to verify - the bounds. - - Ordinal - Ordinal number for the directory at the PathEntryOffset above. - - VerifyBounds - Indicates whether we need to check the validity of - this entry. - - CompoundPathEntry - PathEnumeration context and in-memory path entry. This - has been initialized outside of this call. - -Return Value: - - None. - ---*/ - -{ - PPATH_ENUM_CONTEXT PathContext = &CompoundPathEntry->PathContext; - LONGLONG CurrentBaseOffset; - - PAGED_CODE(); - - // - // Compute the starting base and starting path table offset. - // - - CurrentBaseOffset = SectorTruncate( PathEntryOffset ); - - // - // Map the next block in the Path Table. - // - - CdMapPathTableBlock( IrpContext, - IrpContext->Vcb->PathTableFcb, - CurrentBaseOffset, - PathContext ); - - // - // Set up our current offset into the Path Context. - // - - PathContext->DataOffset = PathEntryOffset - PathContext->BaseOffset; - - // - // Update the in-memory structure for this path entry. - // - - (VOID) CdUpdatePathEntryFromRawPathEntry( IrpContext, - Ordinal, - VerifyBounds, - &CompoundPathEntry->PathContext, - &CompoundPathEntry->PathEntry ); -} - - -BOOLEAN -CdLookupNextPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN OUT PPATH_ENUM_CONTEXT PathContext, - IN OUT PPATH_ENTRY PathEntry - ) - -/*++ - -Routine Description: - - This routine is called to move to the next path table entry. We know - the offset and the length of the current entry. We start by computing - the offset of the next entry and determine if it is contained in the - table. Then we check to see if we need to move to the next sector in - the path table. We always map two sectors at a time so we don't - have to deal with any path entries which span sectors. We move to - the next sector if we are in the second sector of the current mapped - data block. - - We look up the next entry and update the path entry structure with - the values out of the raw sector but don't update the CdName structure. - -Arguments: - - PathContext - Enumeration context for this scan of the path table. - - PathEntry - In-memory representation of the on-disk path table entry. - -Return Value: - - BOOLEAN - TRUE if another entry is found, FALSE otherwise. - This routine may raise on error. - ---*/ - -{ - LONGLONG CurrentBaseOffset; - - PAGED_CODE(); - - // - // Get the offset of the next path entry within the current - // data block. - // - - PathContext->DataOffset += PathEntry->PathEntryLength; - - // - // If we are in the last data block then check if we are beyond the - // end of the file. - // - - if (PathContext->LastDataBlock) { - - if (PathContext->DataOffset >= PathContext->DataLength) { - - return FALSE; - } - - // - // If we are not in the last data block of the path table and - // this offset is in the second sector then move to the next - // data block. - // - - } else if (PathContext->DataOffset >= SECTOR_SIZE) { - - CurrentBaseOffset = PathContext->BaseOffset + SECTOR_SIZE; - - CdMapPathTableBlock( IrpContext, - IrpContext->Vcb->PathTableFcb, - CurrentBaseOffset, - PathContext ); - - // - // Set up our current offset into the Path Context. - // - - PathContext->DataOffset -= SECTOR_SIZE; - } - - // - // Now update the path entry with the values from the on-disk - // structure. - // - - return CdUpdatePathEntryFromRawPathEntry( IrpContext, - PathEntry->Ordinal + 1, - TRUE, - PathContext, - PathEntry ); -} - - -BOOLEAN -CdFindPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN PFCB ParentFcb, - IN PCD_NAME DirName, - IN BOOLEAN IgnoreCase, - IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry - ) - -/*++ - -Routine Description: - - This routine will walk through the path table looking for a matching entry for DirName - among the child directories of the ParentFcb. - -Arguments: - - ParentFcb - This is the directory we are examining. We know the ordinal and path table - offset for this directory in the path table. If this is the first scan for this - Fcb we will update the first child offset for this directory in the path table. - - DirName - This is the name we are searching for. This name will not contain wildcard - characters. The name will also not have a version string. - - IgnoreCase - Indicates if this search is exact or ignore case. - - CompoundPathEntry - Complete path table enumeration structure. We will have initialized - it for the search on entry. This will be positioned at the matching name if found. - -Return Value: - - BOOLEAN - TRUE if matching entry found, FALSE otherwise. - ---*/ - -{ - BOOLEAN Found = FALSE; - BOOLEAN UpdateChildOffset = TRUE; - - ULONG StartingOffset; - ULONG StartingOrdinal; - - PAGED_CODE(); - - // - // Position ourselves at either the first child or at the directory itself. - // Lock the Fcb to get this value and remember whether to update with the first - // child. - // - - StartingOffset = CdQueryFidPathTableOffset( ParentFcb->FileId ); - StartingOrdinal = ParentFcb->Ordinal; - - // - // ISO 9660 9.4.4 restricts the backpointer from child to parent in a - // pathtable entry to 16bits. Although we internally store ordinals - // as 32bit values, it is impossible to search for the children of a - // directory whose ordinal value is greater than MAXUSHORT. Media that - // could induce such a search is illegal. - // - // Note that it is not illegal to have more than MAXUSHORT directories. - // - - if (ParentFcb->Ordinal > MAXUSHORT) { - - CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); - } - - CdLockFcb( IrpContext, ParentFcb ); - - if (ParentFcb->ChildPathTableOffset != 0) { - - StartingOffset = ParentFcb->ChildPathTableOffset; - StartingOrdinal = ParentFcb->ChildOrdinal; - UpdateChildOffset = FALSE; - - } else if (ParentFcb == ParentFcb->Vcb->RootIndexFcb) { - - UpdateChildOffset = FALSE; - } - - CdUnlockFcb( IrpContext, ParentFcb ); - - CdLookupPathEntry( IrpContext, StartingOffset, StartingOrdinal, FALSE, CompoundPathEntry ); - - // - // Loop until we find a match or are beyond the children for this directory. - // - - do { - - // - // If we are beyond this directory then return FALSE. - // - - if (CompoundPathEntry->PathEntry.ParentOrdinal > ParentFcb->Ordinal) { - - // - // Update the Fcb with the offsets for the children in the path table. - // - - if (UpdateChildOffset) { - - CdLockFcb( IrpContext, ParentFcb ); - - ParentFcb->ChildPathTableOffset = StartingOffset; - ParentFcb->ChildOrdinal = StartingOrdinal; - - CdUnlockFcb( IrpContext, ParentFcb ); - } - - break; - } - - // - // If we are within the children of this directory then check for a match. - // - - if (CompoundPathEntry->PathEntry.ParentOrdinal == ParentFcb->Ordinal) { - - // - // Update the child offset if not yet done. - // - - if (UpdateChildOffset) { - - CdLockFcb( IrpContext, ParentFcb ); - - ParentFcb->ChildPathTableOffset = CompoundPathEntry->PathEntry.PathTableOffset; - ParentFcb->ChildOrdinal = CompoundPathEntry->PathEntry.Ordinal; - - CdUnlockFcb( IrpContext, ParentFcb ); - - UpdateChildOffset = FALSE; - } - - // - // Update the name in the path entry. - // - - CdUpdatePathEntryName( IrpContext, &CompoundPathEntry->PathEntry, IgnoreCase ); - - // - // Now compare the names for an exact match. - // - - if (CdIsNameInExpression( IrpContext, - &CompoundPathEntry->PathEntry.CdCaseDirName, - DirName, - 0, - FALSE )) { - - // - // Let our caller know we have a match. - // - - Found = TRUE; - break; - } - } - - // - // Go to the next entry in the path table. Remember the current position - // in the event we update the Fcb. - // - - StartingOffset = CompoundPathEntry->PathEntry.PathTableOffset; - StartingOrdinal = CompoundPathEntry->PathEntry.Ordinal; - - } while (CdLookupNextPathEntry( IrpContext, - &CompoundPathEntry->PathContext, - &CompoundPathEntry->PathEntry )); - - return Found; -} - - -// -// Local support routine -// - -VOID -CdMapPathTableBlock ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN LONGLONG BaseOffset, - IN OUT PPATH_ENUM_CONTEXT PathContext - ) - -/*++ - -Routine Description: - - This routine is called to map (or allocate and copy) the next - data block in the path table. We check if the next block will - span a view boundary and allocate an auxilary buffer in that case. - -Arguments: - - Fcb - This is the Fcb for the Path Table. - - BaseOffset - Offset of the first sector to map. This will be on a - sector boundary. - - PathContext - Enumeration context to update in this routine. - -Return Value: - - None. - ---*/ - -{ - ULONG CurrentLength; - ULONG SectorSize; - ULONG DataOffset; - ULONG PassCount; - PVOID Sector; - - PAGED_CODE(); - - // - // Map the new block and set the enumeration context to this - // point. Allocate an auxilary buffer if necessary. - // - - CurrentLength = 2 * SECTOR_SIZE; - - if (CurrentLength >= (ULONG) (Fcb->FileSize.QuadPart - BaseOffset)) { - - CurrentLength = (ULONG) (Fcb->FileSize.QuadPart - BaseOffset); - - // - // We know this is the last data block for this - // path table. - // - - PathContext->LastDataBlock = TRUE; - } - - // - // Set context values. - // - - PathContext->BaseOffset = (ULONG) BaseOffset; - PathContext->DataLength = CurrentLength; - - // - // Drop the previous sector's mapping - // - - CdUnpinData( IrpContext, &PathContext->Bcb ); - - // - // Check if spanning a view section. The following must - // be true before we take this step. - // - // Data length is more than one sector. - // Starting offset must be one sector before the - // cache manager VACB boundary. - // - - if ((CurrentLength > SECTOR_SIZE) && - (FlagOn( ((ULONG) BaseOffset), VACB_MAPPING_MASK ) == LAST_VACB_SECTOR_OFFSET )) { - - // - // Map each sector individually and store into an auxilary - // buffer. - // - - SectorSize = SECTOR_SIZE; - DataOffset = 0; - PassCount = 2; - - PathContext->Data = FsRtlAllocatePoolWithTag( CdPagedPool, - CurrentLength, - TAG_SPANNING_PATH_TABLE ); - PathContext->AllocatedData = TRUE; - - while (PassCount--) { - - CcMapData( Fcb->FileObject, - (PLARGE_INTEGER) &BaseOffset, - SectorSize, - TRUE, - &PathContext->Bcb, - &Sector ); - - RtlCopyMemory( Add2Ptr( PathContext->Data, DataOffset, PVOID ), - Sector, - SectorSize ); - - CdUnpinData( IrpContext, &PathContext->Bcb ); - - BaseOffset += SECTOR_SIZE; - SectorSize = CurrentLength - SECTOR_SIZE; - DataOffset = SECTOR_SIZE; - } - - // - // Otherwise we can just map the data into the cache. - // - - } else { - - // - // There is a slight chance that we have allocated an - // auxilary buffer on the previous sector. - // - - if (PathContext->AllocatedData) { - - CdFreePool( &PathContext->Data ); - PathContext->AllocatedData = FALSE; - } - - CcMapData( Fcb->FileObject, - (PLARGE_INTEGER) &BaseOffset, - CurrentLength, - TRUE, - &PathContext->Bcb, - &PathContext->Data ); - } - - return; -} - - -// -// Local support routine -// - -BOOLEAN -CdUpdatePathEntryFromRawPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN ULONG Ordinal, - IN BOOLEAN VerifyBounds, - IN PPATH_ENUM_CONTEXT PathContext, - OUT PPATH_ENTRY PathEntry - ) - -/*++ - -Routine Description: - - This routine is called to update the in-memory Path Entry from the on-disk - path entry. We also do a careful check of the bounds if requested and we - are in the last data block of the path table. - -Arguments: - - Ordinal - Ordinal number for this directory. - - VerifyBounds - Check that the current raw Path Entry actually fits - within the data block. - - PathContext - Current path table enumeration context. - - PathEntry - Pointer to the in-memory path entry structure. - -Return Value: - - TRUE if updated ok, - FALSE if we've hit the end of the pathtable - zero name length && PT size is a multiple - of blocksize. This is a workaround for some Video CDs. Win 9x works around this. - - This routine may raise. - ---*/ - -{ - PRAW_PATH_ENTRY RawPathEntry = CdRawPathEntry( IrpContext, PathContext ); - ULONG RemainingDataLength; - - PAGED_CODE(); - - // - // Check for a name length of zero. This is the first byte of the record, - // and there must be at least one byte remaining in the buffer else we - // wouldn't be here (caller would have spotted buffer end). - // - - PathEntry->DirNameLen = CdRawPathIdLen( IrpContext, RawPathEntry ); - - if (0 == PathEntry->DirNameLen) { - - // - // If we are in the last block, and the path table size (ie last block) is a - // multiple of block size, then we will consider this the end of the path table - // rather than raising an error. Workaround for NTI Cd Maker video CDs which - // round path table length to blocksize multiple. In all other cases we consider - // a zero length name to be corruption. - // - - if ( PathContext->LastDataBlock && - (0 == BlockOffset( IrpContext->Vcb, PathContext->DataLength))) { - - return FALSE; - } - - CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); - } - - // - // Check if we should verify the path entry. If we are not in the last - // data block then there is nothing to check. - // - - if (PathContext->LastDataBlock && VerifyBounds) { - - // - // Quick check to see if the maximum size is still available. This - // will handle most cases and we don't need to access any of the - // fields. - // - - RemainingDataLength = PathContext->DataLength - PathContext->DataOffset; - - if (RemainingDataLength < sizeof( RAW_PATH_ENTRY )) { - - // - // Make sure the remaining bytes hold the path table entries. - // Do the following checks. - // - // - A minimal path table entry will fit (and then check) - // - This path table entry (with dir name) will fit. - // - - if ((RemainingDataLength < MIN_RAW_PATH_ENTRY_LEN) || - (RemainingDataLength < (ULONG) (CdRawPathIdLen( IrpContext, RawPathEntry ) + MIN_RAW_PATH_ENTRY_LEN - 1))) { - - CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); - } - } - } - - // - // The ordinal number of this directory is passed in. - // Compute the path table offset of this entry. - // - - PathEntry->Ordinal = Ordinal; - PathEntry->PathTableOffset = PathContext->BaseOffset + PathContext->DataOffset; - - // - // We know we can safely access all of the fields of the raw path table at - // this point. - - // - // Bias the disk offset by the number of logical blocks - // - - CopyUchar4( &PathEntry->DiskOffset, CdRawPathLoc( IrpContext, RawPathEntry )); - - PathEntry->DiskOffset += CdRawPathXar( IrpContext, RawPathEntry ); - - CopyUchar2( &PathEntry->ParentOrdinal, &RawPathEntry->ParentNum ); - - PathEntry->PathEntryLength = PathEntry->DirNameLen + MIN_RAW_PATH_ENTRY_LEN - 1; - - // - // Align the path entry length on a ushort boundary. - // - - PathEntry->PathEntryLength = WordAlign( PathEntry->PathEntryLength ); - - PathEntry->DirName = (PCHAR)RawPathEntry->DirId; /* ReactOS Change: GCC "assignment makes pointer from integer without a cast" */ - - return TRUE; -} - - -// -// Local support routine -// - -VOID -CdUpdatePathEntryName ( - IN PIRP_CONTEXT IrpContext, - IN OUT PPATH_ENTRY PathEntry, - IN BOOLEAN IgnoreCase - ) - -/*++ - -Routine Description: - - This routine will store the directory name into the CdName in the - path entry. If this is a Joliet name then we will make sure we have - an allocated buffer and need to convert from big endian to little - endian. We also correctly update the case name. If this operation is ignore - case then we need an auxilary buffer for the name. - - For an Ansi disk we can use the name from the disk for the exact case. We only - need to allocate a buffer for the ignore case name. The on-disk representation of - a Unicode name is useless for us. In this case we will need a name buffer for - both names. We store a buffer in the PathEntry which can hold two 8.3 unicode - names. This means we will almost never need to allocate a buffer in the Ansi case - (we only need one buffer and already have 48 characters). - -Arguments: - - PathEntry - Pointer to a path entry structure. We have already updated - this path entry with the values from the raw path entry. - -Return Value: - - None. - ---*/ - -{ - ULONG Length; - NTSTATUS Status; - - PAGED_CODE(); - - // - // Check if this is a self entry. We use a fixed string for this. - // - // Self-Entry - Length is 1, value is 0. - // - - if ((*PathEntry->DirName == 0) && - (PathEntry->DirNameLen == 1)) { - - // - // There should be no allocated buffers. - // - - ASSERT( !FlagOn( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )); - - // - // Now use one of the hard coded directory names. - // - - PathEntry->CdDirName.FileName = CdUnicodeDirectoryNames[0]; - - // - // Show that there is no version number. - // - - PathEntry->CdDirName.VersionString.Length = 0; - - // - // The case name is identical. - // - - PathEntry->CdCaseDirName = PathEntry->CdDirName; - - // - // Return now. - // - - return; - } - - // - // Compute how large a buffer we will need. If this is an ignore - // case operation then we will want a double size buffer. If the disk is not - // a Joliet disk then we might need two bytes for each byte in the name. - // - - Length = PathEntry->DirNameLen; - - if (IgnoreCase) { - - Length *= 2; - } - - if (!FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) { - - Length *= sizeof( WCHAR ); - } - - // - // Now decide if we need to allocate a new buffer. We will if - // this name won't fit in the embedded name buffer and it is - // larger than the current allocated buffer. We always use the - // allocated buffer if present. - // - // If we haven't allocated a buffer then use the embedded buffer if the data - // will fit. This is the typical case. - // - - if (!FlagOn( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER ) && - (Length <= sizeof( PathEntry->NameBuffer ))) { - - PathEntry->CdDirName.FileName.MaximumLength = sizeof( PathEntry->NameBuffer ); - PathEntry->CdDirName.FileName.Buffer = PathEntry->NameBuffer; - - } else { - - // - // We need to use an allocated buffer. Check if the current buffer - // is large enough. - // - - if (Length > PathEntry->CdDirName.FileName.MaximumLength) { - - // - // Free any allocated buffer. - // - - if (FlagOn( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )) { - - CdFreePool( &PathEntry->CdDirName.FileName.Buffer ); - ClearFlag( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER ); - } - - PathEntry->CdDirName.FileName.Buffer = FsRtlAllocatePoolWithTag( CdPagedPool, - Length, - TAG_PATH_ENTRY_NAME ); - - SetFlag( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER ); - - PathEntry->CdDirName.FileName.MaximumLength = (USHORT) Length; - } - } - - // - // We now have a buffer for the name. We need to either convert the on-disk bigendian - // to little endian or covert the name to Unicode. - // - - if (!FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) { - - Status = RtlOemToUnicodeN( PathEntry->CdDirName.FileName.Buffer, - PathEntry->CdDirName.FileName.MaximumLength, - &Length, - PathEntry->DirName, - PathEntry->DirNameLen ); - - ASSERT( Status == STATUS_SUCCESS ); - PathEntry->CdDirName.FileName.Length = (USHORT) Length; - - } else { - - // - // Convert this string to little endian. - // - - CdConvertBigToLittleEndian( IrpContext, - PathEntry->DirName, - PathEntry->DirNameLen, - (PCHAR) PathEntry->CdDirName.FileName.Buffer ); - - PathEntry->CdDirName.FileName.Length = (USHORT) PathEntry->DirNameLen; - } - - // - // There is no version string. - // - - PathEntry->CdDirName.VersionString.Length = - PathEntry->CdCaseDirName.VersionString.Length = 0; - - // - // If the name string ends with a period then knock off the last - // character. - // - - if (PathEntry->CdDirName.FileName.Buffer[(PathEntry->CdDirName.FileName.Length - sizeof( WCHAR )) / 2] == L'.') { - - // - // Shrink the filename length. - // - - PathEntry->CdDirName.FileName.Length -= sizeof( WCHAR ); - } - - // - // Update the case name buffer if necessary. If this is an exact case - // operation then just copy the exact case string. - // - - if (IgnoreCase) { - - PathEntry->CdCaseDirName.FileName.Buffer = Add2Ptr( PathEntry->CdDirName.FileName.Buffer, - PathEntry->CdDirName.FileName.MaximumLength / 2, - PWCHAR); - - PathEntry->CdCaseDirName.FileName.MaximumLength = PathEntry->CdDirName.FileName.MaximumLength / 2; - - CdUpcaseName( IrpContext, - &PathEntry->CdDirName, - &PathEntry->CdCaseDirName ); - - } else { - - PathEntry->CdCaseDirName = PathEntry->CdDirName; - } - - return; -} - - diff --git a/reactos/drivers/filesystems/cdfs_new/pnp.c b/reactos/drivers/filesystems/cdfs_new/pnp.c deleted file mode 100755 index 48f8dc4e1f7..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/pnp.c +++ /dev/null @@ -1,793 +0,0 @@ -/*++ - -Copyright (c) 1997-2000 Microsoft Corporation - -Module Name: - - Pnp.c - -Abstract: - - This module implements the Plug and Play routines for CDFS called by - the dispatch driver. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_PNP) - -NTSTATUS -CdPnpQueryRemove ( - PIRP_CONTEXT IrpContext, - PIRP Irp, - PVCB Vcb - ); - -NTSTATUS -CdPnpRemove ( - PIRP_CONTEXT IrpContext, - PIRP Irp, - PVCB Vcb - ); - -NTSTATUS -CdPnpSurpriseRemove ( - PIRP_CONTEXT IrpContext, - PIRP Irp, - PVCB Vcb - ); - -NTSTATUS -CdPnpCancelRemove ( - PIRP_CONTEXT IrpContext, - PIRP Irp, - PVCB Vcb - ); - -NTSTATUS -CdPnpCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Contxt - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCommonPnp) -#pragma alloc_text(PAGE, CdPnpCancelRemove) -#pragma alloc_text(PAGE, CdPnpQueryRemove) -#pragma alloc_text(PAGE, CdPnpRemove) -#pragma alloc_text(PAGE, CdPnpSurpriseRemove) -#endif - - -NTSTATUS -CdCommonPnp ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the common routine for doing PnP operations called - by both the fsd and fsp threads - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - BOOLEAN PassThrough = FALSE; - - PIO_STACK_LOCATION IrpSp; - - PVOLUME_DEVICE_OBJECT OurDeviceObject; - PVCB Vcb; - - // - // Get the current Irp stack location. - // - - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - // - // Find our Vcb. This is tricky since we have no file object in the Irp. - // - - OurDeviceObject = (PVOLUME_DEVICE_OBJECT) IrpSp->DeviceObject; - - // - // IO holds a handle reference on our VDO and holds the device lock, which - // syncs us against mounts/verifies. However we hold no reference on the - // volume, which may already have been torn down (and the Vpb freed), for - // example by a force dismount. Check for this condition. We must hold this - // lock until the pnp worker functions take additional locks/refs on the Vcb. - // - - CdAcquireCdData( IrpContext); - - // - // Make sure this device object really is big enough to be a volume device - // object. If it isn't, we need to get out before we try to reference some - // field that takes us past the end of an ordinary device object. - // - - if (OurDeviceObject->DeviceObject.Size != sizeof(VOLUME_DEVICE_OBJECT) || - NodeType( &OurDeviceObject->Vcb ) != CDFS_NTC_VCB) { - - // - // We were called with something we don't understand. - // - - Status = STATUS_INVALID_PARAMETER; - CdReleaseCdData( IrpContext); - CdCompleteRequest( IrpContext, Irp, Status ); - return Status; - } - - // - // Force all PnP operations to be synchronous. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); - - Vcb = &OurDeviceObject->Vcb; - - // - // Check that the Vcb hasn't already been deleted. If so, just pass the - // request through to the driver below, we don't need to do anything. - // - - if (NULL == Vcb->Vpb) { - - PassThrough = TRUE; - } - else { - - // - // Case on the minor code. - // - - switch ( IrpSp->MinorFunction ) { - - case IRP_MN_QUERY_REMOVE_DEVICE: - - Status = CdPnpQueryRemove( IrpContext, Irp, Vcb ); - break; - - case IRP_MN_SURPRISE_REMOVAL: - - Status = CdPnpSurpriseRemove( IrpContext, Irp, Vcb ); - break; - - case IRP_MN_REMOVE_DEVICE: - - Status = CdPnpRemove( IrpContext, Irp, Vcb ); - break; - - case IRP_MN_CANCEL_REMOVE_DEVICE: - - Status = CdPnpCancelRemove( IrpContext, Irp, Vcb ); - break; - - default: - - PassThrough = TRUE; - break; - } - } - - if (PassThrough) { - - CdReleaseCdData( IrpContext); - - // - // Just pass the IRP on. As we do not need to be in the - // way on return, ellide ourselves out of the stack. - // - - IoSkipCurrentIrpStackLocation( Irp ); - - Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); - - // - // Cleanup our Irp Context. The driver has completed the Irp. - // - - CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); - } - - return Status; -} - - -NTSTATUS -CdPnpQueryRemove ( - PIRP_CONTEXT IrpContext, - PIRP Irp, - PVCB Vcb - ) - -/*++ - -Routine Description: - - This routine handles the PnP query remove operation. The filesystem - is responsible for answering whether there are any reasons it sees - that the volume can not go away (and the device removed). Initiation - of the dismount begins when we answer yes to this question. - - Query will be followed by a Cancel or Remove. - -Arguments: - - Irp - Supplies the Irp to process - - Vcb - Supplies the volume being queried. - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - KEVENT Event; - BOOLEAN VcbPresent = TRUE; - - ASSERT_EXCLUSIVE_CDDATA; - - // - // Having said yes to a QUERY, any communication with the - // underlying storage stack is undefined (and may block) - // until the bounding CANCEL or REMOVE is sent. - // - // Acquire the global resource so that we can try to vaporize the volume, - // and the vcb resource itself. - // - - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - // - // Drop a reference on the Vcb to keep it around after we drop the locks. - // - - CdLockVcb( IrpContext, Vcb); - Vcb->VcbReference += 1; - CdUnlockVcb( IrpContext, Vcb); - - CdReleaseCdData( IrpContext); - - Status = CdLockVolumeInternal( IrpContext, Vcb, NULL ); - - // - // Reacquire the global lock, which means dropping the Vcb resource. - // - - CdReleaseVcb( IrpContext, Vcb ); - - CdAcquireCdData( IrpContext ); - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - // - // Remove our extra reference. - // - - CdLockVcb( IrpContext, Vcb); - Vcb->VcbReference -= 1; - CdUnlockVcb( IrpContext, Vcb); - - if (NT_SUCCESS( Status )) { - - // - // We need to pass this down before starting the dismount, which - // could disconnect us immediately from the stack. - // - - // - // Get the next stack location, and copy over the stack location - // - - IoCopyCurrentIrpStackLocationToNext( Irp ); - - // - // Set up the completion routine - // - - KeInitializeEvent( &Event, NotificationEvent, FALSE ); - IoSetCompletionRoutine( Irp, - CdPnpCompletionRoutine, - &Event, - TRUE, - TRUE, - TRUE ); - - // - // Send the request and wait. - // - - Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); - - if (Status == STATUS_PENDING) { - - KeWaitForSingleObject( &Event, - Executive, - KernelMode, - FALSE, - NULL ); - - Status = Irp->IoStatus.Status; - } - - // - // Now if no one below us failed already, initiate the dismount - // on this volume, make it go away. PnP needs to see our internal - // streams close and drop their references to the target device. - // - // Since we were able to lock the volume, we are guaranteed to - // move this volume into dismount state and disconnect it from - // the underlying storage stack. The force on our part is actually - // unnecesary, though complete. - // - // What is not strictly guaranteed, though, is that the closes - // for the metadata streams take effect synchronously underneath - // of this call. This would leave references on the target device - // even though we are disconnected! - // - - if (NT_SUCCESS( Status )) { - - VcbPresent = CdCheckForDismount( IrpContext, Vcb, TRUE ); - - ASSERT( !VcbPresent || Vcb->VcbCondition == VcbDismountInProgress ); - } - - // - // Note: Normally everything will complete and the internal streams will - // vaporise. However there is some code in the system which drops additional - // references on fileobjects, including our internal stream file objects, - // for (WMI) tracing purposes. If that happens to run concurrently with our - // teardown, our internal streams will not vaporise until those references - // are removed. So it's possible that the volume still remains at this - // point. The pnp query remove will fail due to our references on the device. - // To be cleaner we will return an error here. We could pend the pnp - // IRP until the volume goes away, but since we don't know when that will - // be, and this is a very rare case, we'll just fail the query. - // - // The reason this is the case is that handles/fileobjects place a reference - // on the device objects they overly. In the filesystem case, these references - // are on our target devices. PnP correcly thinks that if references remain - // on the device objects in the stack that someone has a handle, and that this - // counts as a reason to not succeed the query - even though every interrogated - // driver thinks that it is OK. - // - - if (NT_SUCCESS( Status) && VcbPresent && (Vcb->VcbReference != 0)) { - - Status = STATUS_DEVICE_BUSY; - } - } - - // - // Release the Vcb if it could still remain. - // - - if (VcbPresent) { - - CdReleaseVcb( IrpContext, Vcb ); - } - - CdReleaseCdData( IrpContext ); - - // - // Cleanup our IrpContext and complete the IRP if neccesary. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - - return Status; -} - - -NTSTATUS -CdPnpRemove ( - PIRP_CONTEXT IrpContext, - PIRP Irp, - PVCB Vcb - ) - -/*++ - -Routine Description: - - This routine handles the PnP remove operation. This is our notification - that the underlying storage device for the volume we have is gone, and - an excellent indication that the volume will never reappear. The filesystem - is responsible for initiation or completion the dismount. - -Arguments: - - Irp - Supplies the Irp to process - - Vcb - Supplies the volume being removed. - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - KEVENT Event; - BOOLEAN VcbPresent = TRUE; - - ASSERT_EXCLUSIVE_CDDATA; - - // - // REMOVE - a storage device is now gone. We either got - // QUERY'd and said yes OR got a SURPRISE OR a storage - // stack failed to spin back up from a sleep/stop state - // (the only case in which this will be the first warning). - // - // Note that it is entirely unlikely that we will be around - // for a REMOVE in the first two cases, as we try to intiate - // dismount. - // - - // - // Acquire the global resource so that we can try to vaporize - // the volume, and the vcb resource itself. - // - - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - // - // The device will be going away. Remove our lock and find - // out if we ever had one in the first place. - // - - Status = CdUnlockVolumeInternal( IrpContext, Vcb, NULL ); - - // - // If the volume had not been locked, we must invalidate the - // volume to ensure it goes away properly. The remove will - // succeed. - // - - if (!NT_SUCCESS( Status )) { - - CdLockVcb( IrpContext, Vcb ); - - if (Vcb->VcbCondition != VcbDismountInProgress) { - - CdUpdateVcbCondition( Vcb, VcbInvalid); - } - - CdUnlockVcb( IrpContext, Vcb ); - - Status = STATUS_SUCCESS; - } - - // - // We need to pass this down before starting the dismount, which - // could disconnect us immediately from the stack. - // - - // - // Get the next stack location, and copy over the stack location - // - - IoCopyCurrentIrpStackLocationToNext( Irp ); - - // - // Set up the completion routine - // - - KeInitializeEvent( &Event, NotificationEvent, FALSE ); - IoSetCompletionRoutine( Irp, - CdPnpCompletionRoutine, - &Event, - TRUE, - TRUE, - TRUE ); - - // - // Send the request and wait. - // - - Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); - - if (Status == STATUS_PENDING) { - - KeWaitForSingleObject( &Event, - Executive, - KernelMode, - FALSE, - NULL ); - - Status = Irp->IoStatus.Status; - } - - // - // Now make our dismount happen. This may not vaporize the - // Vcb, of course, since there could be any number of handles - // outstanding if we were not preceeded by a QUERY. - // - // PnP will take care of disconnecting this stack if we - // couldn't get off of it immediately. - // - - - VcbPresent = CdCheckForDismount( IrpContext, Vcb, TRUE ); - - // - // Release the Vcb if it could still remain. - // - - if (VcbPresent) { - - CdReleaseVcb( IrpContext, Vcb ); - } - - CdReleaseCdData( IrpContext ); - - // - // Cleanup our IrpContext and complete the IRP. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - - return Status; -} - - -NTSTATUS -CdPnpSurpriseRemove ( - PIRP_CONTEXT IrpContext, - PIRP Irp, - PVCB Vcb - ) - -/*++ - -Routine Description: - - This routine handles the PnP surprise remove operation. This is another - type of notification that the underlying storage device for the volume we - have is gone, and is excellent indication that the volume will never reappear. - The filesystem is responsible for initiation or completion the dismount. - - For the most part, only "real" drivers care about the distinction of a - surprise remove, which is a result of our noticing that a user (usually) - physically reached into the machine and pulled something out. - - Surprise will be followed by a Remove when all references have been shut down. - -Arguments: - - Irp - Supplies the Irp to process - - Vcb - Supplies the volume being removed. - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - KEVENT Event; - BOOLEAN VcbPresent = TRUE; - - ASSERT_EXCLUSIVE_CDDATA; - - // - // SURPRISE - a device was physically yanked away without - // any warning. This means external forces. - // - - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - // - // Invalidate the volume right now. - // - // The intent here is to make every subsequent operation - // on the volume fail and grease the rails toward dismount. - // By definition there is no going back from a SURPRISE. - // - - CdLockVcb( IrpContext, Vcb ); - - if (Vcb->VcbCondition != VcbDismountInProgress) { - - CdUpdateVcbCondition( Vcb, VcbInvalid); - } - - CdUnlockVcb( IrpContext, Vcb ); - - // - // We need to pass this down before starting the dismount, which - // could disconnect us immediately from the stack. - // - - // - // Get the next stack location, and copy over the stack location - // - - IoCopyCurrentIrpStackLocationToNext( Irp ); - - // - // Set up the completion routine - // - - KeInitializeEvent( &Event, NotificationEvent, FALSE ); - IoSetCompletionRoutine( Irp, - CdPnpCompletionRoutine, - &Event, - TRUE, - TRUE, - TRUE ); - - // - // Send the request and wait. - // - - Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); - - if (Status == STATUS_PENDING) { - - KeWaitForSingleObject( &Event, - Executive, - KernelMode, - FALSE, - NULL ); - - Status = Irp->IoStatus.Status; - } - - // - // Now make our dismount happen. This may not vaporize the - // Vcb, of course, since there could be any number of handles - // outstanding since this is an out of band notification. - // - - - VcbPresent = CdCheckForDismount( IrpContext, Vcb, TRUE ); - - // - // Release the Vcb if it could still remain. - // - - if (VcbPresent) { - - CdReleaseVcb( IrpContext, Vcb ); - } - - CdReleaseCdData( IrpContext ); - - // - // Cleanup our IrpContext and complete the IRP. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - - return Status; -} - - -NTSTATUS -CdPnpCancelRemove ( - PIRP_CONTEXT IrpContext, - PIRP Irp, - PVCB Vcb - ) - -/*++ - -Routine Description: - - This routine handles the PnP cancel remove operation. This is our - notification that a previously proposed remove (query) was eventually - vetoed by a component. The filesystem is responsible for cleaning up - and getting ready for more IO. - -Arguments: - - Irp - Supplies the Irp to process - - Vcb - Supplies the volume being removed. - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status; - - ASSERT_EXCLUSIVE_CDDATA; - - // - // CANCEL - a previous QUERY has been rescinded as a result - // of someone vetoing. Since PnP cannot figure out who may - // have gotten the QUERY (think about it: stacked drivers), - // we must expect to deal with getting a CANCEL without having - // seen the QUERY. - // - // For CDFS, this is quite easy. In fact, we can't get a - // CANCEL if the underlying drivers succeeded the QUERY since - // we disconnect the Vpb on our dismount initiation. This is - // actually pretty important because if PnP could get to us - // after the disconnect we'd be thoroughly unsynchronized - // with respect to the Vcb getting torn apart - merely referencing - // the volume device object is insufficient to keep us intact. - // - - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - CdReleaseCdData( IrpContext); - - // - // Unlock the volume. This is benign if we never had seen - // a QUERY. - // - - (VOID) CdUnlockVolumeInternal( IrpContext, Vcb, NULL ); - - CdReleaseVcb( IrpContext, Vcb ); - - // - // Send the request. The underlying driver will complete the - // IRP. Since we don't need to be in the way, simply ellide - // ourselves out of the IRP stack. - // - - IoSkipCurrentIrpStackLocation( Irp ); - - Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); - - CdCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdPnpCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Contxt - ) -{ - PKEVENT Event = (PKEVENT) Contxt; - - KeSetEvent( Event, 0, FALSE ); - - return STATUS_MORE_PROCESSING_REQUIRED; - - UNREFERENCED_PARAMETER( DeviceObject ); - UNREFERENCED_PARAMETER( Contxt ); -} - - diff --git a/reactos/drivers/filesystems/cdfs_new/prefxsup.c b/reactos/drivers/filesystems/cdfs_new/prefxsup.c deleted file mode 100755 index c00b98e50e9..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/prefxsup.c +++ /dev/null @@ -1,711 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - PrefxSup.c - -Abstract: - - This module implements the Cdfs Prefix support routines - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_PREFXSUP) - -// -// Local support routines. -// - -PNAME_LINK -CdFindNameLink ( - IN PIRP_CONTEXT IrpContext, - IN PRTL_SPLAY_LINKS *RootNode, - IN PUNICODE_STRING Name - ); - -BOOLEAN -CdInsertNameLink ( - IN PIRP_CONTEXT IrpContext, - IN PRTL_SPLAY_LINKS *RootNode, - IN PNAME_LINK NameLink - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdFindNameLink) -#pragma alloc_text(PAGE, CdFindPrefix) -#pragma alloc_text(PAGE, CdInsertNameLink) -#pragma alloc_text(PAGE, CdInsertPrefix) -#pragma alloc_text(PAGE, CdRemovePrefix) -#endif - - -VOID -CdInsertPrefix ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PCD_NAME Name, - IN BOOLEAN IgnoreCase, - IN BOOLEAN ShortNameMatch, - IN PFCB ParentFcb - ) - -/*++ - -Routine Description: - - This routine inserts the names in the given Lcb into the links for the - parent. - -Arguments: - - Fcb - This is the Fcb whose name is being inserted into the tree. - - Name - This is the name for the component. The IgnoreCase flag tells - us which entry this belongs to. - - IgnoreCase - Indicates if we should insert the case-insensitive name. - - ShortNameMatch - Indicates if this is the short name. - - ParentFcb - This is the ParentFcb. The prefix tree is attached to this. - -Return Value: - - None. - ---*/ - -{ - ULONG PrefixFlags; - PNAME_LINK NameLink; - PPREFIX_ENTRY PrefixEntry; - PRTL_SPLAY_LINKS *TreeRoot; - - PWCHAR NameBuffer; - - PAGED_CODE(); - - // - // Check if we need to allocate a prefix entry for the short name. - // If we can't allocate one then fail quietly. We don't have to - // insert the name. - // - - PrefixEntry = &Fcb->FileNamePrefix; - - if (ShortNameMatch) { - - if (Fcb->ShortNamePrefix == NULL) { - - Fcb->ShortNamePrefix = ExAllocatePoolWithTag( CdPagedPool, - sizeof( PREFIX_ENTRY ), - TAG_PREFIX_ENTRY ); - - if (Fcb->ShortNamePrefix == NULL) { return; } - - RtlZeroMemory( Fcb->ShortNamePrefix, sizeof( PREFIX_ENTRY )); - } - - PrefixEntry = Fcb->ShortNamePrefix; - } - - // - // Capture the local variables for the separate cases. - // - - if (IgnoreCase) { - - PrefixFlags = PREFIX_FLAG_IGNORE_CASE_IN_TREE; - NameLink = &PrefixEntry->IgnoreCaseName; - TreeRoot = &ParentFcb->IgnoreCaseRoot; - - } else { - - PrefixFlags = PREFIX_FLAG_EXACT_CASE_IN_TREE; - NameLink = &PrefixEntry->ExactCaseName; - TreeRoot = &ParentFcb->ExactCaseRoot; - } - - // - // If neither name is in the tree then check whether we have a buffer for this - // name - // - - if (!FlagOn( PrefixEntry->PrefixFlags, - PREFIX_FLAG_EXACT_CASE_IN_TREE | PREFIX_FLAG_IGNORE_CASE_IN_TREE )) { - - // - // Allocate a new buffer if the embedded buffer is too small. - // - - NameBuffer = PrefixEntry->FileNameBuffer; - - if (Name->FileName.Length > BYTE_COUNT_EMBEDDED_NAME) { - - NameBuffer = ExAllocatePoolWithTag( CdPagedPool, - Name->FileName.Length * 2, - TAG_PREFIX_NAME ); - - // - // Exit if no name buffer. - // - - if (NameBuffer == NULL) { return; } - } - - // - // Split the buffer and fill in the separate components. - // - - PrefixEntry->ExactCaseName.FileName.Buffer = NameBuffer; - PrefixEntry->IgnoreCaseName.FileName.Buffer = Add2Ptr( NameBuffer, - Name->FileName.Length, - PWCHAR ); - - PrefixEntry->IgnoreCaseName.FileName.MaximumLength = - PrefixEntry->IgnoreCaseName.FileName.Length = - PrefixEntry->ExactCaseName.FileName.MaximumLength = - PrefixEntry->ExactCaseName.FileName.Length = Name->FileName.Length; - } - - // - // Only insert the name if not already present. - // - - if (!FlagOn( PrefixEntry->PrefixFlags, PrefixFlags )) { - - // - // Initialize the name in the prefix entry. - // - - RtlCopyMemory( NameLink->FileName.Buffer, - Name->FileName.Buffer, - Name->FileName.Length ); - - CdInsertNameLink( IrpContext, - TreeRoot, - NameLink ); - - PrefixEntry->Fcb = Fcb; - SetFlag( PrefixEntry->PrefixFlags, PrefixFlags ); - } - - return; -} - - -VOID -CdRemovePrefix ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb - ) - -/*++ - -Routine Description: - - This routine is called to remove all of the previx entries of a - given Fcb from its parent Fcb. - -Arguments: - - Fcb - Fcb whose entries are to be removed. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // - // Start with the short name prefix entry. - // - - if (Fcb->ShortNamePrefix != NULL) { - - if (FlagOn( Fcb->ShortNamePrefix->PrefixFlags, PREFIX_FLAG_IGNORE_CASE_IN_TREE )) { - - Fcb->ParentFcb->IgnoreCaseRoot = RtlDelete( &Fcb->ShortNamePrefix->IgnoreCaseName.Links ); - } - - if (FlagOn( Fcb->ShortNamePrefix->PrefixFlags, PREFIX_FLAG_EXACT_CASE_IN_TREE )) { - - Fcb->ParentFcb->ExactCaseRoot = RtlDelete( &Fcb->ShortNamePrefix->ExactCaseName.Links ); - } - - ClearFlag( Fcb->ShortNamePrefix->PrefixFlags, - PREFIX_FLAG_IGNORE_CASE_IN_TREE | PREFIX_FLAG_EXACT_CASE_IN_TREE ); - } - - // - // Now do the long name prefix entries. - // - - if (FlagOn( Fcb->FileNamePrefix.PrefixFlags, PREFIX_FLAG_IGNORE_CASE_IN_TREE )) { - - Fcb->ParentFcb->IgnoreCaseRoot = RtlDelete( &Fcb->FileNamePrefix.IgnoreCaseName.Links ); - } - - if (FlagOn( Fcb->FileNamePrefix.PrefixFlags, PREFIX_FLAG_EXACT_CASE_IN_TREE )) { - - Fcb->ParentFcb->ExactCaseRoot = RtlDelete( &Fcb->FileNamePrefix.ExactCaseName.Links ); - } - - ClearFlag( Fcb->FileNamePrefix.PrefixFlags, - PREFIX_FLAG_IGNORE_CASE_IN_TREE | PREFIX_FLAG_EXACT_CASE_IN_TREE ); - - // - // Deallocate any buffer we may have allocated. - // - - if ((Fcb->FileNamePrefix.ExactCaseName.FileName.Buffer != (PWCHAR) &Fcb->FileNamePrefix.FileNameBuffer) && - (Fcb->FileNamePrefix.ExactCaseName.FileName.Buffer != NULL)) { - - CdFreePool( &Fcb->FileNamePrefix.ExactCaseName.FileName.Buffer ); - Fcb->FileNamePrefix.ExactCaseName.FileName.Buffer = NULL; - } - - return; -} - - -VOID -CdFindPrefix ( - IN PIRP_CONTEXT IrpContext, - IN OUT PFCB *CurrentFcb, - IN OUT PUNICODE_STRING RemainingName, - IN BOOLEAN IgnoreCase - ) - -/*++ - -Routine Description: - - This routine begins from the given CurrentFcb and walks through all of - components of the name looking for the longest match in the prefix - splay trees. The search is relative to the starting Fcb so the - full name may not begin with a '\'. On return this routine will - update Current Fcb with the lowest point it has travelled in the - tree. It will also hold only that resource on return and it must - hold that resource. - -Arguments: - - CurrentFcb - Address to store the lowest Fcb we find on this search. - On return we will have acquired this Fcb. On entry this is the - Fcb to examine. - - RemainingName - Supplies a buffer to store the exact case of the name being - searched for. Initially will contain the upcase name based on the - IgnoreCase flag. - - IgnoreCase - Indicates if we are doing a case-insensitive compare. - -Return Value: - - None - ---*/ - -{ - UNICODE_STRING LocalRemainingName; - - UNICODE_STRING FinalName; - - PNAME_LINK NameLink; - PPREFIX_ENTRY PrefixEntry; - - PAGED_CODE(); - - // - // Make a local copy of the input strings. - // - - LocalRemainingName = *RemainingName; - - // - // Loop until we find the longest matching prefix. - // - - while (TRUE) { - - // - // If there are no characters left or we are not at an IndexFcb then - // return immediately. - // - - if ((LocalRemainingName.Length == 0) || - (SafeNodeType( *CurrentFcb ) != CDFS_NTC_FCB_INDEX)) { - - return; - } - - // - // Split off the next component from the name. - // - - CdDissectName( IrpContext, - &LocalRemainingName, - &FinalName ); - - // - // Check if this name is in the splay tree for this Scb. - // - - if (IgnoreCase) { - - NameLink = CdFindNameLink( IrpContext, - &(*CurrentFcb)->IgnoreCaseRoot, - &FinalName ); - - // - // Get the prefix entry from this NameLink. Don't access any - // fields within it until we verify we have a name link. - // - - PrefixEntry = (PPREFIX_ENTRY) CONTAINING_RECORD( NameLink, - PREFIX_ENTRY, - IgnoreCaseName ); - - } else { - - NameLink = CdFindNameLink( IrpContext, - &(*CurrentFcb)->ExactCaseRoot, - &FinalName ); - - PrefixEntry = (PPREFIX_ENTRY) CONTAINING_RECORD( NameLink, - PREFIX_ENTRY, - ExactCaseName ); - } - - // - // If we didn't find a match then exit. - // - - if (NameLink == NULL) { return; } - - // - // If this is a case-insensitive match then copy the exact case of the name into - // the input buffer. - // - - if (IgnoreCase) { - - RtlCopyMemory( FinalName.Buffer, - PrefixEntry->ExactCaseName.FileName.Buffer, - PrefixEntry->ExactCaseName.FileName.Length ); - } - - // - // Update the caller's remaining name string to reflect the fact that we found - // a match. - // - - *RemainingName = LocalRemainingName; - - // - // Move down to the next component in the tree. Acquire without waiting. - // If this fails then lock the Fcb to reference this Fcb and then drop - // the parent and acquire the child. - // - - if (!CdAcquireFcbExclusive( IrpContext, PrefixEntry->Fcb, TRUE )) { - - // - // If we can't wait then raise CANT_WAIT. - // - - if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - CdRaiseStatus( IrpContext, STATUS_CANT_WAIT ); - } - - CdLockVcb( IrpContext, IrpContext->Vcb ); - PrefixEntry->Fcb->FcbReference += 1; - CdUnlockVcb( IrpContext, IrpContext->Vcb ); - - CdReleaseFcb( IrpContext, *CurrentFcb ); - CdAcquireFcbExclusive( IrpContext, PrefixEntry->Fcb, FALSE ); - - CdLockVcb( IrpContext, IrpContext->Vcb ); - PrefixEntry->Fcb->FcbReference -= 1; - CdUnlockVcb( IrpContext, IrpContext->Vcb ); - - } else { - - CdReleaseFcb( IrpContext, *CurrentFcb ); - } - - *CurrentFcb = PrefixEntry->Fcb; - } -} - - -// -// Local support routine -// - -PNAME_LINK -CdFindNameLink ( - IN PIRP_CONTEXT IrpContext, - IN PRTL_SPLAY_LINKS *RootNode, - IN PUNICODE_STRING Name - ) - -/*++ - -Routine Description: - - This routine searches through a splay link tree looking for a match for the - input name. If we find the corresponding name we will rebalance the - tree. - -Arguments: - - RootNode - Supplies the parent to search. - - Name - This is the name to search for. Note if we are doing a case - insensitive search the name would have been upcased already. - -Return Value: - - PNAME_LINK - The name link found or NULL if there is no match. - ---*/ - -{ - FSRTL_COMPARISON_RESULT Comparison; - PNAME_LINK Node; - PRTL_SPLAY_LINKS Links; - - PAGED_CODE(); - - Links = *RootNode; - - while (Links != NULL) { - - Node = CONTAINING_RECORD( Links, NAME_LINK, Links ); - - // - // Compare the prefix in the tree with the full name - // - - Comparison = CdFullCompareNames( IrpContext, &Node->FileName, Name ); - - // - // See if they don't match - // - - if (Comparison == GreaterThan) { - - // - // The prefix is greater than the full name - // so we go down the left child - // - - Links = RtlLeftChild( Links ); - - // - // And continue searching down this tree - // - - } else if (Comparison == LessThan) { - - // - // The prefix is less than the full name - // so we go down the right child - // - - Links = RtlRightChild( Links ); - - // - // And continue searching down this tree - // - - } else { - - // - // We found it. - // - // Splay the tree and save the new root. - // - - *RootNode = RtlSplay( Links ); - - return Node; - } - } - - // - // We didn't find the Link. - // - - return NULL; -} - - -// -// Local support routine -// - -BOOLEAN -CdInsertNameLink ( - IN PIRP_CONTEXT IrpContext, - IN PRTL_SPLAY_LINKS *RootNode, - IN PNAME_LINK NameLink - ) - -/*++ - -Routine Description: - - This routine will insert a name in the splay tree pointed to - by RootNode. - - The name could already exist in this tree for a case-insensitive tree. - In that case we simply return FALSE and do nothing. - -Arguments: - - RootNode - Supplies a pointer to the table. - - NameLink - Contains the new link to enter. - -Return Value: - - BOOLEAN - TRUE if the name is inserted, FALSE otherwise. - ---*/ - -{ - FSRTL_COMPARISON_RESULT Comparison; - PNAME_LINK Node; - - PAGED_CODE(); - - RtlInitializeSplayLinks( &NameLink->Links ); - - // - // If we are the first entry in the tree, just become the root. - // - - if (*RootNode == NULL) { - - *RootNode = &NameLink->Links; - - return TRUE; - } - - Node = CONTAINING_RECORD( *RootNode, NAME_LINK, Links ); - - while (TRUE) { - - // - // Compare the prefix in the tree with the prefix we want - // to insert. - // - - Comparison = CdFullCompareNames( IrpContext, &Node->FileName, &NameLink->FileName ); - - // - // If we found the entry, return immediately. - // - - if (Comparison == EqualTo) { return FALSE; } - - // - // If the tree prefix is greater than the new prefix then - // we go down the left subtree - // - - if (Comparison == GreaterThan) { - - // - // We want to go down the left subtree, first check to see - // if we have a left subtree - // - - if (RtlLeftChild( &Node->Links ) == NULL) { - - // - // there isn't a left child so we insert ourselves as the - // new left child - // - - RtlInsertAsLeftChild( &Node->Links, &NameLink->Links ); - - // - // and exit the while loop - // - - break; - - } else { - - // - // there is a left child so simply go down that path, and - // go back to the top of the loop - // - - Node = CONTAINING_RECORD( RtlLeftChild( &Node->Links ), - NAME_LINK, - Links ); - } - - } else { - - // - // The tree prefix is either less than or a proper prefix - // of the new string. We treat both cases as less than when - // we do insert. So we want to go down the right subtree, - // first check to see if we have a right subtree - // - - if (RtlRightChild( &Node->Links ) == NULL) { - - // - // These isn't a right child so we insert ourselves as the - // new right child - // - - RtlInsertAsRightChild( &Node->Links, &NameLink->Links ); - - // - // and exit the while loop - // - - break; - - } else { - - // - // there is a right child so simply go down that path, and - // go back to the top of the loop - // - - Node = CONTAINING_RECORD( RtlRightChild( &Node->Links ), - NAME_LINK, - Links ); - } - } - } - - return TRUE; -} - - - - - diff --git a/reactos/drivers/filesystems/cdfs_new/read.c b/reactos/drivers/filesystems/cdfs_new/read.c deleted file mode 100755 index 9e18fd30431..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/read.c +++ /dev/null @@ -1,550 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - Read.c - -Abstract: - - This module implements the File Read routine for Read called by the - Fsd/Fsp dispatch drivers. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_READ) - -// -// VOID -// SafeZeroMemory ( -// IN PUCHAR At, -// IN ULONG ByteCount -// ); -// - -// -// This macro just puts a nice little try-except around RtlZeroMemory -// - -#define SafeZeroMemory(IC,AT,BYTE_COUNT) { \ - try { \ - RtlZeroMemory( (AT), (BYTE_COUNT) ); \ - } except( EXCEPTION_EXECUTE_HANDLER ) { \ - CdRaiseStatus( IC, STATUS_INVALID_USER_BUFFER ); \ - } \ -} - -// -// Read ahead amount used for normal data files -// - -#define READ_AHEAD_GRANULARITY (0x10000) - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCommonRead) -#endif - - -NTSTATUS -CdCommonRead ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the common entry point for NtReadFile calls. For synchronous requests, - CommonRead will complete the request in the current thread. If not - synchronous the request will be passed to the Fsp if there is a need to - block. - -Arguments: - - Irp - Supplies the Irp to process - -Return Value: - - NTSTATUS - The result of this operation. - ---*/ - -{ - NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC Uninit var */ - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - TYPE_OF_OPEN TypeOfOpen; - PFCB Fcb; - PCCB Ccb; - - BOOLEAN Wait; - ULONG PagingIo; - ULONG SynchronousIo; - ULONG NonCachedIo; - PVOID UserBuffer; - - LONGLONG StartingOffset; - LONGLONG ByteRange; - ULONG ByteCount; - ULONG ReadByteCount; - ULONG OriginalByteCount; - - PVOID SystemBuffer; - - BOOLEAN ReleaseFile = TRUE; - - CD_IO_CONTEXT LocalIoContext; - - PAGED_CODE(); - - // - // If this is a zero length read then return SUCCESS immediately. - // - - if (IrpSp->Parameters.Read.Length == 0) { - - CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); - return STATUS_SUCCESS; - } - - // - // Decode the file object and verify we support read on this. It - // must be a user file, stream file or volume file (for a data disk). - // - - TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ); - - if ((TypeOfOpen == UnopenedFileObject) || - (TypeOfOpen == UserDirectoryOpen)) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST ); - return STATUS_INVALID_DEVICE_REQUEST; - } - - // - // Examine our input parameters to determine if this is noncached and/or - // a paging io operation. - // - - Wait = BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); - PagingIo = FlagOn( Irp->Flags, IRP_PAGING_IO ); - NonCachedIo = FlagOn( Irp->Flags, IRP_NOCACHE ); - SynchronousIo = FlagOn( IrpSp->FileObject->Flags, FO_SYNCHRONOUS_IO ); - - - // - // Extract the range of the Io. - // - - StartingOffset = IrpSp->Parameters.Read.ByteOffset.QuadPart; - OriginalByteCount = ByteCount = IrpSp->Parameters.Read.Length; - - ByteRange = StartingOffset + ByteCount; - - // - // Make sure that Dasd access is always non-cached. - // - - if (TypeOfOpen == UserVolumeOpen) { - - NonCachedIo = TRUE; - } - - // - // Acquire the file shared to perform the read. If we are doing paging IO, - // it may be the case that we would have a deadlock imminent because we may - // block on shared access, so starve out any exclusive waiters. This requires - // a degree of caution - we believe that any paging IO bursts will recede and - // allow the exclusive waiter in. - // - - if (PagingIo) { - - CdAcquireFileSharedStarveExclusive( IrpContext, Fcb ); - - } else { - - CdAcquireFileShared( IrpContext, Fcb ); - } - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Verify the Fcb. Allow reads if this is a DASD handle that is - // dismounting the volume. - // - - if ((TypeOfOpen != UserVolumeOpen) || (NULL == Ccb) || - !FlagOn( Ccb->Flags, CCB_FLAG_DISMOUNT_ON_CLOSE)) { - - CdVerifyFcbOperation( IrpContext, Fcb ); - } - - // - // If this is a non-cached then check whether we need to post this - // request if this thread can't block. - // - - if (!Wait && NonCachedIo) { - - // - // XA requests must always be waitable. - // - - if (FlagOn( Fcb->FcbState, FCB_STATE_RAWSECTOR_MASK )) { - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST ); - try_return( Status = STATUS_CANT_WAIT ); - } - } - - // - // If this is a user request then verify the oplock and filelock state. - // - - if (TypeOfOpen == UserFileOpen) { - - // - // We check whether we can proceed - // based on the state of the file oplocks. - // - - Status = FsRtlCheckOplock( &Fcb->Oplock, - Irp, - IrpContext, - (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - (PVOID)CdPrePostIrp );/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - - // - // If the result is not STATUS_SUCCESS then the Irp was completed - // elsewhere. - // - - if (Status != STATUS_SUCCESS) { - - Irp = NULL; - IrpContext = NULL; - - try_return( NOTHING ); - } - - if (!PagingIo && - (Fcb->FileLock != NULL) && - !FsRtlCheckLockForReadAccess( Fcb->FileLock, Irp )) { - - try_return( Status = STATUS_FILE_LOCK_CONFLICT ); - } - } - - // - // Complete the request if it begins beyond the end of file. - // - - if (StartingOffset >= Fcb->FileSize.QuadPart) { - - try_return( Status = STATUS_END_OF_FILE ); - } - - // - // Truncate the read if it extends beyond the end of the file. - // - - if (ByteRange > Fcb->FileSize.QuadPart) { - - ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset); - ByteRange = Fcb->FileSize.QuadPart; - } - - // - // Handle the non-cached read first. - // - - if (NonCachedIo) { - - // - // If we have an unaligned transfer then post this request if - // we can't wait. Unaligned means that the starting offset - // is not on a sector boundary or the read is not integral - // sectors. - // - - ReadByteCount = BlockAlign( Fcb->Vcb, ByteCount ); - - if (SectorOffset( StartingOffset ) || - SectorOffset( ReadByteCount ) || - (ReadByteCount > OriginalByteCount)) { - - if (!Wait) { - - CdRaiseStatus( IrpContext, STATUS_CANT_WAIT ); - } - - // - // Make sure we don't overwrite the buffer. - // - - ReadByteCount = ByteCount; - } - - // - // Initialize the IoContext for the read. - // If there is a context pointer, we need to make sure it was - // allocated and not a stale stack pointer. - // - - if (IrpContext->IoContext == NULL || - !FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO )) { - - // - // If we can wait, use the context on the stack. Otherwise - // we need to allocate one. - // - - if (Wait) { - - IrpContext->IoContext = &LocalIoContext; - ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO ); - - } else { - - IrpContext->IoContext = CdAllocateIoContext(); - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO ); - } - } - - RtlZeroMemory( IrpContext->IoContext, sizeof( CD_IO_CONTEXT )); - - // - // Store whether we allocated this context structure in the structure - // itself. - // - - IrpContext->IoContext->AllocatedContext = - BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO ); - - if (Wait) { - - KeInitializeEvent( &IrpContext->IoContext->SyncEvent, - NotificationEvent, - FALSE ); - - } else { - - IrpContext->IoContext->ResourceThreadId = ExGetCurrentResourceThread(); - IrpContext->IoContext->Resource = Fcb->Resource; - IrpContext->IoContext->RequestedByteCount = ByteCount; - } - - Irp->IoStatus.Information = ReadByteCount; - - // - // Call one of the NonCacheIo routines to perform the actual - // read. - // - - if (FlagOn( Fcb->FcbState, FCB_STATE_RAWSECTOR_MASK )) { - - Status = CdNonCachedXARead( IrpContext, Fcb, StartingOffset, ReadByteCount ); - - } else { - - Status = CdNonCachedRead( IrpContext, Fcb, StartingOffset, ReadByteCount ); - } - - // - // Don't complete this request now if STATUS_PENDING was returned. - // - - if (Status == STATUS_PENDING) { - - Irp = NULL; - ReleaseFile = FALSE; - - // - // Test is we should zero part of the buffer or update the - // synchronous file position. - // - - } else { - - // - // Convert any unknown error code to IO_ERROR. - // - - if (!NT_SUCCESS( Status )) { - - // - // Set the information field to zero. - // - - Irp->IoStatus.Information = 0; - - // - // Raise if this is a user induced error. - // - - if (IoIsErrorUserInduced( Status )) { - - CdRaiseStatus( IrpContext, Status ); - } - - Status = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR ); - - // - // Check if there is any portion of the user's buffer to zero. - // - - } else if (ReadByteCount != ByteCount) { - - CdMapUserBuffer( IrpContext, &UserBuffer); - - SafeZeroMemory( IrpContext, - Add2Ptr( UserBuffer, - ByteCount, - PVOID ), - ReadByteCount - ByteCount ); - - Irp->IoStatus.Information = ByteCount; - } - - // - // Update the file position if this is a synchronous request. - // - - if (SynchronousIo && !PagingIo && NT_SUCCESS( Status )) { - - IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange; - } - } - - try_return( NOTHING ); - } - - // - // Handle the cached case. Start by initializing the private - // cache map. - // - - if (IrpSp->FileObject->PrivateCacheMap == NULL) { - - // - // Now initialize the cache map. - // - - CcInitializeCacheMap( IrpSp->FileObject, - (PCC_FILE_SIZES) &Fcb->AllocationSize, - FALSE, - &CdData.CacheManagerCallbacks, - Fcb ); - - CcSetReadAheadGranularity( IrpSp->FileObject, READ_AHEAD_GRANULARITY ); - } - - // - // Read from the cache if this is not an Mdl read. - // - - if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) { - - // - // If we are in the Fsp now because we had to wait earlier, - // we must map the user buffer, otherwise we can use the - // user's buffer directly. - // - - CdMapUserBuffer( IrpContext, &SystemBuffer ); - - // - // Now try to do the copy. - // - - if (!CcCopyRead( IrpSp->FileObject, - (PLARGE_INTEGER) &StartingOffset, - ByteCount, - Wait, - SystemBuffer, - &Irp->IoStatus )) { - - try_return( Status = STATUS_CANT_WAIT ); - } - - // - // If the call didn't succeed, raise the error status - // - - if (!NT_SUCCESS( Irp->IoStatus.Status )) { - - CdNormalizeAndRaiseStatus( IrpContext, Irp->IoStatus.Status ); - } - - // - // Otherwise perform the MdlRead operation. - // - - } else { - - CcMdlRead( IrpSp->FileObject, - (PLARGE_INTEGER) &StartingOffset, - ByteCount, - &Irp->MdlAddress, - &Irp->IoStatus ); - - Status = Irp->IoStatus.Status; - } - - // - // Update the current file position in the user file object. - // - - if (SynchronousIo && !PagingIo && NT_SUCCESS( Status )) { - - IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange; - } - - try_exit: NOTHING; - } finally { - - // - // Release the Fcb. - // - - if (ReleaseFile) { - - CdReleaseFile( IrpContext, Fcb ); - } - } - - // - // Post the request if we got CANT_WAIT. - // - - if (Status == STATUS_CANT_WAIT) { - - Status = CdFsdPostRequest( IrpContext, Irp ); - - // - // Otherwise complete the request. - // - - } else { - - CdCompleteRequest( IrpContext, Irp, Status ); - } - - return Status; -} - - diff --git a/reactos/drivers/filesystems/cdfs_new/resrcsup.c b/reactos/drivers/filesystems/cdfs_new/resrcsup.c deleted file mode 100755 index abfecdcad06..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/resrcsup.c +++ /dev/null @@ -1,338 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - ResrcSup.c - -Abstract: - - This module implements the Cdfs Resource acquisition routines - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_RESRCSUP) - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdAcquireForCache) -#pragma alloc_text(PAGE, CdAcquireForCreateSection) -#pragma alloc_text(PAGE, CdAcquireResource) -#pragma alloc_text(PAGE, CdNoopAcquire) -#pragma alloc_text(PAGE, CdNoopRelease) -#pragma alloc_text(PAGE, CdReleaseForCreateSection) -#pragma alloc_text(PAGE, CdReleaseFromCache) -#endif - - -BOOLEAN -CdAcquireResource ( - IN PIRP_CONTEXT IrpContext, - IN PERESOURCE Resource, - IN BOOLEAN IgnoreWait, - IN TYPE_OF_ACQUIRE Type - ) - -/*++ - -Routine Description: - - This is the single routine used to acquire file system resources. It - looks at the IgnoreWait flag to determine whether to try to acquire the - resource without waiting. Returning TRUE/FALSE to indicate success or - failure. Otherwise it is driven by the WAIT flag in the IrpContext and - will raise CANT_WAIT on a failure. - -Arguments: - - Resource - This is the resource to try and acquire. - - IgnoreWait - If TRUE then this routine will not wait to acquire the - resource and will return a boolean indicating whether the resource was - acquired. Otherwise we use the flag in the IrpContext and raise - if the resource is not acquired. - - Type - Indicates how we should try to get the resource. - -Return Value: - - BOOLEAN - TRUE if the resource is acquired. FALSE if not acquired and - IgnoreWait is specified. Otherwise we raise CANT_WAIT. - ---*/ - -{ - BOOLEAN Wait = FALSE; - BOOLEAN Acquired; - PAGED_CODE(); - - // - // We look first at the IgnoreWait flag, next at the flag in the Irp - // Context to decide how to acquire this resource. - // - - if (!IgnoreWait && FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { - - Wait = TRUE; - } - - // - // Attempt to acquire the resource either shared or exclusively. - // - - switch (Type) { - case AcquireExclusive: - - Acquired = ExAcquireResourceExclusiveLite( Resource, Wait ); - break; - - case AcquireShared: - - Acquired = ExAcquireResourceSharedLite( Resource, Wait ); - break; - - case AcquireSharedStarveExclusive: - - Acquired = ExAcquireSharedStarveExclusive( Resource, Wait ); - break; - - default: - Acquired = FALSE; - ASSERT( FALSE ); - } - - // - // If not acquired and the user didn't specifiy IgnoreWait then - // raise CANT_WAIT. - // - - if (!Acquired && !IgnoreWait) { - - CdRaiseStatus( IrpContext, STATUS_CANT_WAIT ); - } - - return Acquired; -} - - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdAcquireForCache ( - IN PFCB Fcb, - IN BOOLEAN Wait - ) - -/*++ - -Routine Description: - - The address of this routine is specified when creating a CacheMap for - a file. It is subsequently called by the Lazy Writer for synchronization. - -Arguments: - - Fcb - The pointer supplied as context to the cache initialization - routine. - - Wait - TRUE if the caller is willing to block. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - ASSERT(IoGetTopLevelIrp() == NULL); - IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP); - - return ExAcquireResourceSharedLite( Fcb->Resource, Wait ); -} - - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdReleaseFromCache ( - IN PFCB Fcb - ) - -/*++ - -Routine Description: - - The address of this routine is specified when creating a CacheMap for - a virtual file. It is subsequently called by the Lazy Writer to release - a resource acquired above. - -Arguments: - - Fcb - The pointer supplied as context to the cache initialization - routine. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP); - IoSetTopLevelIrp( NULL ); - - ExReleaseResourceLite( Fcb->Resource ); -} - - -BOOLEAN -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdNoopAcquire ( - IN PVOID Fcb, - IN BOOLEAN Wait - ) - -/*++ - -Routine Description: - - This routine does nothing. - -Arguments: - - Fcb - The Fcb/Vcb which was specified as a context parameter for this - routine. - - Wait - TRUE if the caller is willing to block. - -Return Value: - - TRUE - ---*/ - -{ - PAGED_CODE(); - return TRUE; -} - - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdNoopRelease ( - IN PVOID Fcb - ) - -/*++ - -Routine Description: - - This routine does nothing. - -Arguments: - - Fcb - The Fcb/Vcb which was specified as a context parameter for this - routine. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); -} - - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdAcquireForCreateSection ( - IN PFILE_OBJECT FileObject - ) - -/*++ - -Routine Description: - - This is the callback routine for MM to use to acquire the file exclusively. - -Arguments: - - FileObject - File object for a Cdfs stream. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - - // - // Get the Fcb resource exclusively. - // - - ExAcquireResourceExclusiveLite( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource, - TRUE ); - - // - // Take the File resource shared. We need this later on when MM calls - // QueryStandardInfo to get the file size. - // - // If we don't use StarveExclusive, then we can get wedged behind an - // exclusive waiter who is waiting on someone else holding it shared in the - // read->initializecachemap path (which calls createsection) who is in turn - // waiting on us to finish the create section. - // - - ExAcquireSharedStarveExclusive( ((PFCB) FileObject->FsContext)->Resource, - TRUE ); -} - - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdReleaseForCreateSection ( - IN PFILE_OBJECT FileObject - ) - -/*++ - -Routine Description: - - This is the callback routine for MM to use to release a file acquired with - the AcquireForCreateSection call above. - -Arguments: - - FileObject - File object for a Cdfs stream. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // - // Release the resources. - // - - ExReleaseResourceLite( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource ); - ExReleaseResourceLite( ((PFCB) FileObject->FsContext)->Resource); -} - diff --git a/reactos/drivers/filesystems/cdfs_new/strucsup.c b/reactos/drivers/filesystems/cdfs_new/strucsup.c deleted file mode 100755 index 0ab42dc804a..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/strucsup.c +++ /dev/null @@ -1,2766 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - StrucSup.c - -Abstract: - - This module implements the Cdfs in-memory data structure manipulation - routines - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_STRUCSUP) - -// -// Local macros -// - -// -// PFCB -// CdAllocateFcbData ( -// IN PIRP_CONTEXT IrpContext -// ); -// -// VOID -// CdDeallocateFcbData ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// -// PFCB -// CdAllocateFcbIndex ( -// IN PIRP_CONTEXT IrpContext -// ); -// -// VOID -// CdDeallocateFcbIndex ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// -// PFCB_NONPAGED -// CdAllocateFcbNonpaged ( -// IN PIRP_CONTEXT IrpContext -// ); -// -// VOID -// CdDeallocateFcbNonpaged ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB_NONPAGED FcbNonpaged -// ); -// -// PCCB -// CdAllocateCcb ( -// IN PIRP_CONTEXT IrpContext -// ); -// -// VOID -// CdDeallocateCcb ( -// IN PIRP_CONTEXT IrpContext, -// IN PCCB Ccb -// ); -// - -#define CdAllocateFcbData(IC) \ - FsRtlAllocatePoolWithTag( CdPagedPool, SIZEOF_FCB_DATA, TAG_FCB_DATA ) - -#define CdDeallocateFcbData(IC,F) \ - CdFreePool( &(F) ) - -#define CdAllocateFcbIndex(IC) \ - FsRtlAllocatePoolWithTag( CdPagedPool, SIZEOF_FCB_INDEX, TAG_FCB_INDEX ) - -#define CdDeallocateFcbIndex(IC,F) \ - CdFreePool( &(F) ) - -#define CdAllocateFcbNonpaged(IC) \ - ExAllocatePoolWithTag( CdNonPagedPool, sizeof( FCB_NONPAGED ), TAG_FCB_NONPAGED ) - -#define CdDeallocateFcbNonpaged(IC,FNP) \ - CdFreePool( &(FNP) ) - -#define CdAllocateCcb(IC) \ - FsRtlAllocatePoolWithTag( CdPagedPool, sizeof( CCB ), TAG_CCB ) - -#define CdDeallocateCcb(IC,C) \ - CdFreePool( &(C) ) - -// -// Local structures -// - -typedef struct _FCB_TABLE_ELEMENT { - - FILE_ID FileId; - PFCB Fcb; - -} FCB_TABLE_ELEMENT, *PFCB_TABLE_ELEMENT; - -// -// Local macros -// - -// -// VOID -// CdInsertFcbTable ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// -// VOID -// CdDeleteFcbTable ( -// IN PIRP_CONTEXT IrpContext, -// IN PFCB Fcb -// ); -// - - -#define CdInsertFcbTable(IC,F) { \ - FCB_TABLE_ELEMENT _Key; \ - _Key.Fcb = (F); \ - _Key.FileId = (F)->FileId; \ - RtlInsertElementGenericTable( &(F)->Vcb->FcbTable, \ - &_Key, \ - sizeof( FCB_TABLE_ELEMENT ), \ - NULL ); \ -} - -#define CdDeleteFcbTable(IC,F) { \ - FCB_TABLE_ELEMENT _Key; \ - _Key.FileId = (F)->FileId; \ - RtlDeleteElementGenericTable( &(F)->Vcb->FcbTable, &_Key ); \ -} - -// -// Local support routines -// - -VOID -CdDeleteFcb ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb - ); - -PFCB_NONPAGED -CdCreateFcbNonpaged ( - IN PIRP_CONTEXT IrpContext - ); - -VOID -CdDeleteFcbNonpaged ( - IN PIRP_CONTEXT IrpContext, - IN PFCB_NONPAGED FcbNonpaged - ); - -RTL_GENERIC_COMPARE_RESULTS -CdFcbTableCompare ( - IN PRTL_GENERIC_TABLE FcbTable, - IN PVOID Fid1, - IN PVOID Fid2 - ); - -PVOID -CdAllocateFcbTable ( - IN PRTL_GENERIC_TABLE FcbTable, - IN CLONG ByteSize - ); - -VOID -CdDeallocateFcbTable ( - IN PRTL_GENERIC_TABLE FcbTable, - IN PVOID Buffer - ); - -ULONG -CdTocSerial ( - IN PIRP_CONTEXT IrpContext, - IN PCDROM_TOC CdromToc - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdAllocateFcbTable) -#pragma alloc_text(PAGE, CdCleanupIrpContext) -#pragma alloc_text(PAGE, CdCreateCcb) -#pragma alloc_text(PAGE, CdCreateFcb) -#pragma alloc_text(PAGE, CdCreateFcbNonpaged) -#pragma alloc_text(PAGE, CdCreateFileLock) -#pragma alloc_text(PAGE, CdCreateIrpContext) -#pragma alloc_text(PAGE, CdDeallocateFcbTable) -#pragma alloc_text(PAGE, CdDeleteCcb) -#pragma alloc_text(PAGE, CdDeleteFcb) -#pragma alloc_text(PAGE, CdDeleteFcbNonpaged) -#pragma alloc_text(PAGE, CdDeleteFileLock) -#pragma alloc_text(PAGE, CdDeleteVcb) -#pragma alloc_text(PAGE, CdFcbTableCompare) -#pragma alloc_text(PAGE, CdGetNextFcb) -#pragma alloc_text(PAGE, CdInitializeFcbFromFileContext) -#pragma alloc_text(PAGE, CdInitializeFcbFromPathEntry) -#pragma alloc_text(PAGE, CdInitializeStackIrpContext) -#pragma alloc_text(PAGE, CdInitializeVcb) -#pragma alloc_text(PAGE, CdLookupFcbTable) -#pragma alloc_text(PAGE, CdProcessToc) -#pragma alloc_text(PAGE, CdTeardownStructures) -#pragma alloc_text(PAGE, CdTocSerial) -#pragma alloc_text(PAGE, CdUpdateVcbFromVolDescriptor) -#endif - - -VOID -CdInitializeVcb ( - IN PIRP_CONTEXT IrpContext, - IN OUT PVCB Vcb, - IN PDEVICE_OBJECT TargetDeviceObject, - IN PVPB Vpb, - IN PCDROM_TOC CdromToc, - IN ULONG TocLength, - IN ULONG TocTrackCount, - IN ULONG TocDiskFlags, - IN ULONG BlockFactor, - IN ULONG MediaChangeCount - ) - -/*++ - -Routine Description: - - This routine initializes and inserts a new Vcb record into the in-memory - data structure. The Vcb record "hangs" off the end of the Volume device - object and must be allocated by our caller. - -Arguments: - - Vcb - Supplies the address of the Vcb record being initialized. - - TargetDeviceObject - Supplies the address of the target device object to - associate with the Vcb record. - - Vpb - Supplies the address of the Vpb to associate with the Vcb record. - - CdromToc - Buffer to hold table of contents. NULL if TOC command not - supported. - - TocLength - Byte count length of TOC. We use this as the TOC length to - return on a user query. - - TocTrackCount - Count of tracks in TOC. Used to create pseudo files for - audio disks. - - TocDiskFlags - Flag field to indicate the type of tracks on the disk. - - BlockFactor - Used to decode any multi-session information. - - MediaChangeCount - Initial media change count of the target device - -Return Value: - - None. - ---*/ - -{ - PAGED_CODE(); - - // - // We start by first zeroing out all of the VCB, this will guarantee - // that any stale data is wiped clean. - // - - RtlZeroMemory( Vcb, sizeof( VCB )); - - // - // Set the proper node type code and node byte size. - // - - Vcb->NodeTypeCode = CDFS_NTC_VCB; - Vcb->NodeByteSize = sizeof( VCB ); - - // - // Initialize the DirNotify structs. FsRtlNotifyInitializeSync can raise. - // - - InitializeListHead( &Vcb->DirNotifyList ); - FsRtlNotifyInitializeSync( &Vcb->NotifySync ); - - // - // Pick up a VPB right now so we know we can pull this filesystem stack - // off of the storage stack on demand. This can raise - if it does, - // uninitialize the notify structures before returning. - // - - try { - - Vcb->SwapVpb = FsRtlAllocatePoolWithTag( NonPagedPool, - sizeof( VPB ), - TAG_VPB ); - } - finally { - - if (AbnormalTermination()) { - - FsRtlNotifyUninitializeSync( &Vcb->NotifySync ); - } - } - - // - // Nothing beyond this point should raise. - // - - RtlZeroMemory( Vcb->SwapVpb, sizeof( VPB ) ); - - // - // Initialize the resource variable for the Vcb and files. - // - - ExInitializeResourceLite( &Vcb->VcbResource ); - ExInitializeResourceLite( &Vcb->FileResource ); - ExInitializeFastMutex( &Vcb->VcbMutex ); - - // - // Insert this Vcb record on the CdData.VcbQueue. - // - - InsertHeadList( &CdData.VcbQueue, &Vcb->VcbLinks ); - - // - // Set the Target Device Object and Vpb fields, referencing the - // Target device for the mount. - // - - ObReferenceObject( TargetDeviceObject ); - Vcb->TargetDeviceObject = TargetDeviceObject; - Vcb->Vpb = Vpb; - - // - // Set the removable media flag based on the real device's - // characteristics - // - - if (FlagOn( Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA )) { - - SetFlag( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA ); - } - - // - // Initialize the generic Fcb Table. - // - - RtlInitializeGenericTable( &Vcb->FcbTable, - (PRTL_GENERIC_COMPARE_ROUTINE) CdFcbTableCompare, - (PRTL_GENERIC_ALLOCATE_ROUTINE) CdAllocateFcbTable, - (PRTL_GENERIC_FREE_ROUTINE) CdDeallocateFcbTable, - NULL ); - - // - // Show that we have a mount in progress. - // - - CdUpdateVcbCondition( Vcb, VcbMountInProgress); - - // - // Refererence the Vcb for two reasons. The first is a reference - // that prevents the Vcb from going away on the last close unless - // dismount has already occurred. The second is to make sure - // we don't go into the dismount path on any error during mount - // until we get to the Mount cleanup. - // - - Vcb->VcbReference = 1 + CDFS_RESIDUAL_REFERENCE; - - // - // Update the TOC information in the Vcb. - // - - Vcb->CdromToc = CdromToc; - Vcb->TocLength = TocLength; - Vcb->TrackCount = TocTrackCount; - Vcb->DiskFlags = TocDiskFlags; - - // - // If this disk contains audio tracks only then set the audio flag. - // - - if (TocDiskFlags == CDROM_DISK_AUDIO_TRACK) { - - SetFlag( Vcb->VcbState, VCB_STATE_AUDIO_DISK | VCB_STATE_CDXA ); - } - - // - // Set the block factor. - // - - Vcb->BlockFactor = BlockFactor; - - // - // Set the media change count on the device - // - - CdUpdateMediaChangeCount( Vcb, MediaChangeCount); -} - - -VOID -CdUpdateVcbFromVolDescriptor ( - IN PIRP_CONTEXT IrpContext, - IN OUT PVCB Vcb, - IN PCHAR RawIsoVd OPTIONAL - ) - -/*++ - -Routine Description: - - This routine is called to perform the final initialization of a Vcb from the - volume descriptor on the disk. - -Arguments: - - Vcb - Vcb for the volume being mounted. We have already set the flags for the - type of descriptor. - - RawIsoVd - If specified this is the volume descriptor to use to mount the - volume. Not specified for a raw disk. - -Return Value: - - None - ---*/ - -{ - //ULONG Shift; /* ReactOS Change: GCC Unused variable */ - ULONG StartingBlock; - ULONG ByteCount; - - LONGLONG FileId = 0; - - PRAW_DIRENT RawDirent; - PATH_ENTRY PathEntry; - PCD_MCB_ENTRY McbEntry; - - BOOLEAN UnlockVcb = FALSE; - - PAGED_CODE(); - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Copy the block size and compute the various block masks. - // Block size must not be larger than the sector size. We will - // use a default of the CD physical sector size if we are not - // on a data-full disc. - // - // This must always be set. - // - - Vcb->BlockSize = ( ARGUMENT_PRESENT( RawIsoVd ) ? - CdRvdBlkSz( RawIsoVd, Vcb->VcbState ) : - SECTOR_SIZE ); - - // - // We no longer accept media where blocksize != sector size. - // - - if (Vcb->BlockSize != SECTOR_SIZE) { - - CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); - } - - Vcb->BlocksPerSector = SECTOR_SIZE / Vcb->BlockSize; - Vcb->BlockMask = Vcb->BlockSize - 1; - Vcb->BlockInverseMask = ~Vcb->BlockMask; - - Vcb->BlockToSectorShift = 0; - Vcb->BlockToByteShift = SECTOR_SHIFT; - - // - // If there is a volume descriptor then do the internal Fcb's and - // other Vcb fields. - // - - if (ARGUMENT_PRESENT( RawIsoVd )) { - - // - // Create the path table Fcb and refererence it and the Vcb. - // - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - - Vcb->PathTableFcb = CdCreateFcb( IrpContext, - *((PFILE_ID) &FileId), - CDFS_NTC_FCB_PATH_TABLE, - NULL ); - - CdIncrementReferenceCounts( IrpContext, Vcb->PathTableFcb, 1, 1 ); - CdUnlockVcb( IrpContext, Vcb ); - UnlockVcb = FALSE; - - // - // Compute the stream offset and size of this path table. - // - - StartingBlock = CdRvdPtLoc( RawIsoVd, Vcb->VcbState ); - - ByteCount = CdRvdPtSz( RawIsoVd, Vcb->VcbState ); - - Vcb->PathTableFcb->StreamOffset = BytesFromBlocks( Vcb, - SectorBlockOffset( Vcb, StartingBlock )); - - Vcb->PathTableFcb->FileSize.QuadPart = (LONGLONG) (Vcb->PathTableFcb->StreamOffset + - ByteCount); - - Vcb->PathTableFcb->ValidDataLength.QuadPart = Vcb->PathTableFcb->FileSize.QuadPart; - - Vcb->PathTableFcb->AllocationSize.QuadPart = LlSectorAlign( Vcb->PathTableFcb->FileSize.QuadPart ); - - // - // Now add the mapping information. - // - - CdLockFcb( IrpContext, Vcb->PathTableFcb ); - - CdAddInitialAllocation( IrpContext, - Vcb->PathTableFcb, - StartingBlock, - Vcb->PathTableFcb->AllocationSize.QuadPart ); - - CdUnlockFcb( IrpContext, Vcb->PathTableFcb ); - - // - // Point to the file resource. - // - - Vcb->PathTableFcb->Resource = &Vcb->FileResource; - - // - // Mark the Fcb as initialized and create the stream file for this. - // - - SetFlag( Vcb->PathTableFcb->FcbState, FCB_STATE_INITIALIZED ); - - CdCreateInternalStream( IrpContext, Vcb, Vcb->PathTableFcb ); - - // - // Create the root index and reference it in the Vcb. - // - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - Vcb->RootIndexFcb = CdCreateFcb( IrpContext, - *((PFILE_ID) &FileId), - CDFS_NTC_FCB_INDEX, - NULL ); - - CdIncrementReferenceCounts( IrpContext, Vcb->RootIndexFcb, 1, 1 ); - CdUnlockVcb( IrpContext, Vcb ); - UnlockVcb = FALSE; - - // - // Create the File id by hand for this Fcb. - // - - CdSetFidPathTableOffset( Vcb->RootIndexFcb->FileId, Vcb->PathTableFcb->StreamOffset ); - CdFidSetDirectory( Vcb->RootIndexFcb->FileId ); - - // - // Create a pseudo path table entry so we can call the initialization - // routine for the directory. - // - - RawDirent = (PRAW_DIRENT) CdRvdDirent( RawIsoVd, Vcb->VcbState ); - - CopyUchar4( &PathEntry.DiskOffset, RawDirent->FileLoc ); - - PathEntry.DiskOffset += RawDirent->XarLen; - PathEntry.Ordinal = 1; - PathEntry.PathTableOffset = Vcb->PathTableFcb->StreamOffset; - - CdInitializeFcbFromPathEntry( IrpContext, - Vcb->RootIndexFcb, - NULL, - &PathEntry ); - - // - // Create the stream file for the root directory. - // - - CdCreateInternalStream( IrpContext, Vcb, Vcb->RootIndexFcb ); - - // - // Now do the volume dasd Fcb. Create this and reference it in the - // Vcb. - // - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - - Vcb->VolumeDasdFcb = CdCreateFcb( IrpContext, - *((PFILE_ID) &FileId), - CDFS_NTC_FCB_DATA, - NULL ); - - CdIncrementReferenceCounts( IrpContext, Vcb->VolumeDasdFcb, 1, 1 ); - CdUnlockVcb( IrpContext, Vcb ); - UnlockVcb = FALSE; - - // - // The file size is the full disk. - // - - StartingBlock = CdRvdVolSz( RawIsoVd, Vcb->VcbState ); - - Vcb->VolumeDasdFcb->FileSize.QuadPart = LlBytesFromBlocks( Vcb, StartingBlock ); - - Vcb->VolumeDasdFcb->AllocationSize.QuadPart = - Vcb->VolumeDasdFcb->ValidDataLength.QuadPart = Vcb->VolumeDasdFcb->FileSize.QuadPart; - - // - // Now add the extent representing the volume 'by hand'. - // - - CdLockFcb( IrpContext, Vcb->VolumeDasdFcb ); - - McbEntry = Vcb->VolumeDasdFcb->Mcb.McbArray; - - McbEntry->FileOffset = - McbEntry->DiskOffset = 0; - - McbEntry->ByteCount = Vcb->VolumeDasdFcb->AllocationSize.QuadPart; - - McbEntry->DataBlockByteCount = - McbEntry->TotalBlockByteCount = McbEntry->ByteCount; - - Vcb->VolumeDasdFcb->Mcb.CurrentEntryCount = 1; - - CdUnlockFcb( IrpContext, Vcb->VolumeDasdFcb ); - - // - // Point to the file resource. - // - - Vcb->VolumeDasdFcb->Resource = &Vcb->FileResource; - - Vcb->VolumeDasdFcb->FileAttributes = FILE_ATTRIBUTE_READONLY; - - // - // Mark the Fcb as initialized. - // - - SetFlag( Vcb->VolumeDasdFcb->FcbState, FCB_STATE_INITIALIZED ); - - // - // Check and see if this is an XA disk. - // - - if (FlagOn( Vcb->VcbState, VCB_STATE_ISO | VCB_STATE_JOLIET) - && RtlEqualMemory( CdXaId, - Add2Ptr( RawIsoVd, 0x400, PCHAR ), - 8 )) { - - SetFlag( Vcb->VcbState, VCB_STATE_CDXA ); - } - - // - // If this is a music disk then we want to mock this disk to make it - // look like ISO disk. We will create a pseudo root directory in - // that case. - // - - } else if (FlagOn( Vcb->VcbState, VCB_STATE_AUDIO_DISK )) { - - ULONG RootDirectorySize; - - // - // Create the path table Fcb and refererence it and the Vcb. - // - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - - Vcb->PathTableFcb = CdCreateFcb( IrpContext, - *((PFILE_ID) &FileId), - CDFS_NTC_FCB_PATH_TABLE, - NULL ); - - CdIncrementReferenceCounts( IrpContext, Vcb->PathTableFcb, 1, 1 ); - CdUnlockVcb( IrpContext, Vcb ); - UnlockVcb = FALSE; - - // - // We only create a pseudo entry for the root. - // - - Vcb->PathTableFcb->FileSize.QuadPart = (LONGLONG) (FIELD_OFFSET( RAW_PATH_ISO, DirId ) + 2); - - Vcb->PathTableFcb->ValidDataLength.QuadPart = Vcb->PathTableFcb->FileSize.QuadPart; - - Vcb->PathTableFcb->AllocationSize.QuadPart = LlSectorAlign( Vcb->PathTableFcb->FileSize.QuadPart ); - - // - // Point to the file resource. - // - - Vcb->PathTableFcb->Resource = &Vcb->FileResource; - - // - // Mark the Fcb as initialized and create the stream file for this. - // - - SetFlag( Vcb->PathTableFcb->FcbState, FCB_STATE_INITIALIZED ); - - CdCreateInternalStream( IrpContext, Vcb, Vcb->PathTableFcb ); - - // - // Create the root index and reference it in the Vcb. - // - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - Vcb->RootIndexFcb = CdCreateFcb( IrpContext, - *((PFILE_ID) &FileId), - CDFS_NTC_FCB_INDEX, - NULL ); - - CdIncrementReferenceCounts( IrpContext, Vcb->RootIndexFcb, 1, 1 ); - CdUnlockVcb( IrpContext, Vcb ); - UnlockVcb = FALSE; - - // - // Create the File id by hand for this Fcb. - // - - CdSetFidPathTableOffset( Vcb->RootIndexFcb->FileId, Vcb->PathTableFcb->StreamOffset ); - CdFidSetDirectory( Vcb->RootIndexFcb->FileId ); - - // - // Create a pseudo path table entry so we can call the initialization - // routine for the directory. - // - - RtlZeroMemory( &PathEntry, sizeof( PATH_ENTRY )); - - - PathEntry.Ordinal = 1; - PathEntry.PathTableOffset = Vcb->PathTableFcb->StreamOffset; - - CdInitializeFcbFromPathEntry( IrpContext, - Vcb->RootIndexFcb, - NULL, - &PathEntry ); - - // - // Set the sizes by hand for this Fcb. It should have an entry for each track plus an - // entry for the root and parent. - // - - RootDirectorySize = (Vcb->TrackCount + 2) * CdAudioDirentSize; - RootDirectorySize = SectorAlign( RootDirectorySize ); - - Vcb->RootIndexFcb->AllocationSize.QuadPart = - Vcb->RootIndexFcb->ValidDataLength.QuadPart = - Vcb->RootIndexFcb->FileSize.QuadPart = RootDirectorySize; - - SetFlag( Vcb->RootIndexFcb->FcbState, FCB_STATE_INITIALIZED ); - - // - // Create the stream file for the root directory. - // - - CdCreateInternalStream( IrpContext, Vcb, Vcb->RootIndexFcb ); - - // - // Now do the volume dasd Fcb. Create this and reference it in the - // Vcb. - // - - CdLockVcb( IrpContext, Vcb ); - UnlockVcb = TRUE; - - Vcb->VolumeDasdFcb = CdCreateFcb( IrpContext, - *((PFILE_ID) &FileId), - CDFS_NTC_FCB_DATA, - NULL ); - - CdIncrementReferenceCounts( IrpContext, Vcb->VolumeDasdFcb, 1, 1 ); - CdUnlockVcb( IrpContext, Vcb ); - UnlockVcb = FALSE; - - // - // We won't allow raw reads on this Fcb so leave the size at - // zero. - // - - // - // Point to the file resource. - // - - Vcb->VolumeDasdFcb->Resource = &Vcb->FileResource; - - Vcb->VolumeDasdFcb->FileAttributes = FILE_ATTRIBUTE_READONLY; - - // - // Mark the Fcb as initialized. - // - - SetFlag( Vcb->VolumeDasdFcb->FcbState, FCB_STATE_INITIALIZED ); - - // - // We will store a hard-coded name in the Vpb and use the toc as - // the serial number. - // - - Vcb->Vpb->VolumeLabelLength = CdAudioLabelLength; - - RtlCopyMemory( Vcb->Vpb->VolumeLabel, - CdAudioLabel, - CdAudioLabelLength ); - - // - // Find the serial number for the audio disk. - // - - Vcb->Vpb->SerialNumber = CdTocSerial( IrpContext, Vcb->CdromToc ); - - // - // Set the ISO bit so we know how to treat the names. - // - - SetFlag( Vcb->VcbState, VCB_STATE_ISO ); - } - - } finally { - - if (UnlockVcb) { CdUnlockVcb( IrpContext, Vcb ); } - } -} - - -VOID -CdDeleteVcb ( - IN PIRP_CONTEXT IrpContext, - IN OUT PVCB Vcb - ) - -/*++ - -Routine Description: - - This routine is called to delete a Vcb which failed mount or has been - dismounted. The dismount code should have already removed all of the - open Fcb's. We do nothing here but clean up other auxilary structures. - -Arguments: - - Vcb - Vcb to delete. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - ASSERT_EXCLUSIVE_CDDATA; - ASSERT_EXCLUSIVE_VCB( Vcb ); - - // - // Chuck the backpocket Vpb we kept just in case. - // - - if (Vcb->SwapVpb) { - - CdFreePool( &Vcb->SwapVpb ); - } - - // - // If there is a Vpb then we must delete it ourselves. - // - - if (Vcb->Vpb != NULL) { - - CdFreePool( &Vcb->Vpb ); - } - - // - // Dereference our target if we haven't already done so. - // - - if (Vcb->TargetDeviceObject != NULL) { - - ObDereferenceObject( Vcb->TargetDeviceObject ); - } - - // - // Delete the XA Sector if allocated. - // - - if (Vcb->XASector != NULL) { - - CdFreePool( &Vcb->XASector ); - } - - // - // Remove this entry from the global queue. - // - - RemoveEntryList( &Vcb->VcbLinks ); - - // - // Delete the Vcb and File resources. - // - - ExDeleteResourceLite( &Vcb->VcbResource ); - ExDeleteResourceLite( &Vcb->FileResource ); - - // - // Delete the TOC if present. - // - - if (Vcb->CdromToc != NULL) { - - CdFreePool( &Vcb->CdromToc ); - } - - // - // Uninitialize the notify structures. - // - - if (Vcb->NotifySync != NULL) { - - FsRtlNotifyUninitializeSync( &Vcb->NotifySync ); - } - - // - // Now delete the volume device object. - // - - IoDeleteDevice( (PDEVICE_OBJECT) CONTAINING_RECORD( Vcb, - VOLUME_DEVICE_OBJECT, - Vcb )); - - return; -} - - -PFCB -CdCreateFcb ( - IN PIRP_CONTEXT IrpContext, - IN FILE_ID FileId, - IN NODE_TYPE_CODE NodeTypeCode, - OUT PBOOLEAN FcbExisted OPTIONAL - ) - -/*++ - -Routine Description: - - This routine is called to find the Fcb for the given FileId. We will - look this up first in the Fcb table and if not found we will create - an Fcb. We don't initialize it or insert it into the FcbTable in this - routine. - - This routine is called while the Vcb is locked. - -Arguments: - - FileId - This is the Id for the target Fcb. - - NodeTypeCode - Node type for this Fcb if we need to create. - - FcbExisted - If specified, we store whether the Fcb existed. - -Return Value: - - PFCB - The Fcb found in the table or created if needed. - ---*/ - -{ - PFCB NewFcb; - BOOLEAN LocalFcbExisted; - - PAGED_CODE(); - - // - // Use the local boolean if one was not passed in. - // - - if (!ARGUMENT_PRESENT( FcbExisted )) { - - FcbExisted = &LocalFcbExisted; - } - - // - // Maybe this is already in the table. - // - - NewFcb = CdLookupFcbTable( IrpContext, IrpContext->Vcb, FileId ); - - // - // If not then create the Fcb is requested by our caller. - // - - if (NewFcb == NULL) { - - // - // Allocate and initialize the structure depending on the - // type code. - // - - switch (NodeTypeCode) { - - case CDFS_NTC_FCB_PATH_TABLE: - case CDFS_NTC_FCB_INDEX: - - NewFcb = CdAllocateFcbIndex( IrpContext ); - - RtlZeroMemory( NewFcb, SIZEOF_FCB_INDEX ); - - NewFcb->NodeByteSize = SIZEOF_FCB_INDEX; - - InitializeListHead( &NewFcb->FcbQueue ); - - break; - - case CDFS_NTC_FCB_DATA : - - NewFcb = CdAllocateFcbData( IrpContext ); - - RtlZeroMemory( NewFcb, SIZEOF_FCB_DATA ); - - NewFcb->NodeByteSize = SIZEOF_FCB_DATA; - - break; - - default: - - CdBugCheck( 0, 0, 0 ); - } - - // - // Now do the common initialization. - // - - NewFcb->NodeTypeCode = NodeTypeCode; - - NewFcb->Vcb = IrpContext->Vcb; - NewFcb->FileId = FileId; - - CdInitializeMcb( IrpContext, NewFcb ); - - // - // Now create the non-paged section object. - // - - NewFcb->FcbNonpaged = CdCreateFcbNonpaged( IrpContext ); - - // - // Deallocate the Fcb and raise if the allocation failed. - // - - if (NewFcb->FcbNonpaged == NULL) { - - CdFreePool( &NewFcb ); - - CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); - } - - *FcbExisted = FALSE; - - // - // Initialize Advanced FCB Header fields - // - - ExInitializeFastMutex( &NewFcb->FcbNonpaged->AdvancedFcbHeaderMutex ); - FsRtlSetupAdvancedHeader( &NewFcb->Header, - &NewFcb->FcbNonpaged->AdvancedFcbHeaderMutex ); - } else { - - *FcbExisted = TRUE; - } - - return NewFcb; -} - - -VOID -CdInitializeFcbFromPathEntry ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PFCB ParentFcb OPTIONAL, - IN PPATH_ENTRY PathEntry - ) - -/*++ - -Routine Description: - - This routine is called to initialize an Fcb for a directory from - the path entry. Since we only have a starting point for the directory, - not the length, we can only speculate on the sizes. - - The general initialization is performed in CdCreateFcb. - -Arguments: - - Fcb - Newly created Fcb for this stream. - - ParentFcb - Parent Fcb for this stream. It may not be present. - - PathEntry - PathEntry for this Fcb in the Path Table. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // - // Fill in the Index specific fields of the Fcb. - // - - Fcb->StreamOffset = BytesFromBlocks( Fcb->Vcb, - SectorBlockOffset( Fcb->Vcb, PathEntry->DiskOffset )); - - Fcb->Ordinal = PathEntry->Ordinal; - - // - // Initialize the common header in the Fcb. The node type is already - // present. - // - - Fcb->Resource = &Fcb->Vcb->FileResource; - - // - // Always set the sizes to one sector until we read the self-entry. - // - - Fcb->AllocationSize.QuadPart = - Fcb->FileSize.QuadPart = - Fcb->ValidDataLength.QuadPart = SECTOR_SIZE; - - CdAddInitialAllocation( IrpContext, - Fcb, - PathEntry->DiskOffset, - SECTOR_SIZE ); - // - // State flags for this Fcb. - // - - SetFlag( Fcb->FileAttributes, - FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY ); - - // - // Link into the other in-memory structures and into the Fcb table. - // - - if (ParentFcb != NULL) { - - Fcb->ParentFcb = ParentFcb; - - InsertTailList( &ParentFcb->FcbQueue, &Fcb->FcbLinks ); - - CdIncrementReferenceCounts( IrpContext, ParentFcb, 1, 1 ); - } - - CdInsertFcbTable( IrpContext, Fcb ); - SetFlag( Fcb->FcbState, FCB_STATE_IN_FCB_TABLE ); - - return; -} - - -VOID -CdInitializeFcbFromFileContext ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN PFCB ParentFcb, - IN PFILE_ENUM_CONTEXT FileContext - ) - -/*++ - -Routine Description: - - This routine is called to initialize an Fcb for a file from - the file context. We have looked up all of the dirents for this - stream and have the full file size. We will load the all of the allocation - for the file into the Mcb now. - - The general initialization is performed in CdCreateFcb. - -Arguments: - - Fcb - Newly created Fcb for this stream. - - ParentFcb - Parent Fcb for this stream. - - FileContext - FileContext for the file. - -Return Value: - - None - ---*/ - -{ - PDIRENT ThisDirent = &FileContext->InitialDirent->Dirent; - PCOMPOUND_DIRENT CurrentCompoundDirent; - - LONGLONG CurrentFileOffset; - ULONG CurrentMcbEntryOffset; - - PAGED_CODE(); - - // - // Use a try-finally to facilitate cleanup. - // - - CdLockFcb( IrpContext, Fcb ); - - try { - - // - // Initialize the common header in the Fcb. The node type is already - // present. - // - - Fcb->Resource = &IrpContext->Vcb->FileResource; - - // - // Allocation occurs in block-sized units. - // - - Fcb->FileSize.QuadPart = - Fcb->ValidDataLength.QuadPart = FileContext->FileSize; - - Fcb->AllocationSize.QuadPart = LlBlockAlign( Fcb->Vcb, FileContext->FileSize ); - - // - // Set the flags from the dirent. We always start with the read-only bit. - // - - SetFlag( Fcb->FileAttributes, FILE_ATTRIBUTE_READONLY ); - if (FlagOn( ThisDirent->DirentFlags, CD_ATTRIBUTE_HIDDEN )) { - - SetFlag( Fcb->FileAttributes, FILE_ATTRIBUTE_HIDDEN ); - } - - // - // Convert the time to NT time. - // - - CdConvertCdTimeToNtTime( IrpContext, - ThisDirent->CdTime, - (PLARGE_INTEGER) &Fcb->CreationTime ); - - // - // Set the flag indicating the type of extent. - // - - if (ThisDirent->ExtentType != Form1Data) { - - if (ThisDirent->ExtentType == Mode2Form2Data) { - - SetFlag( Fcb->FcbState, FCB_STATE_MODE2FORM2_FILE ); - - } else { - - SetFlag( Fcb->FcbState, FCB_STATE_DA_FILE ); - } - - Fcb->XAAttributes = ThisDirent->XAAttributes; - Fcb->XAFileNumber = ThisDirent->XAFileNumber; - } - - // - // Read through all of the dirents for the file until we find the last - // and add the allocation into the Mcb. - // - - CurrentCompoundDirent = FileContext->InitialDirent; - CurrentFileOffset = 0; - CurrentMcbEntryOffset = 0; - - while (TRUE) { - - CdAddAllocationFromDirent( IrpContext, - Fcb, - CurrentMcbEntryOffset, - CurrentFileOffset, - &CurrentCompoundDirent->Dirent ); - - // - // Break out if we are at the last dirent. - // - - if (!FlagOn( CurrentCompoundDirent->Dirent.DirentFlags, CD_ATTRIBUTE_MULTI )) { - - break; - } - - CurrentFileOffset += CurrentCompoundDirent->Dirent.DataLength; - CurrentMcbEntryOffset += 1; - - // - // We better be able to find the next dirent. - // - - if (!CdLookupNextDirent( IrpContext, - ParentFcb, - &CurrentCompoundDirent->DirContext, - &FileContext->CurrentDirent->DirContext )) { - - CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); - } - - CurrentCompoundDirent = FileContext->CurrentDirent; - - CdUpdateDirentFromRawDirent( IrpContext, - ParentFcb, - &CurrentCompoundDirent->DirContext, - &CurrentCompoundDirent->Dirent ); - } - - // - // Show that the Fcb is initialized. - // - - SetFlag( Fcb->FcbState, FCB_STATE_INITIALIZED ); - - // - // Link into the other in-memory structures and into the Fcb table. - // - - Fcb->ParentFcb = ParentFcb; - - InsertTailList( &ParentFcb->FcbQueue, &Fcb->FcbLinks ); - - CdIncrementReferenceCounts( IrpContext, ParentFcb, 1, 1 ); - - CdInsertFcbTable( IrpContext, Fcb ); - SetFlag( Fcb->FcbState, FCB_STATE_IN_FCB_TABLE ); - - } finally { - - CdUnlockFcb( IrpContext, Fcb ); - } - - return; -} - - -PCCB -CdCreateCcb ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb, - IN ULONG Flags - ) - -/*++ - -Routine Description: - - This routine is called to allocate and initialize the Ccb structure. - -Arguments: - - Fcb - This is the Fcb for the file being opened. - - Flags - User flags to set in this Ccb. - -Return Value: - - PCCB - Pointer to the created Ccb. - ---*/ - -{ - PCCB NewCcb; - PAGED_CODE(); - - // - // Allocate and initialize the structure. - // - - NewCcb = CdAllocateCcb( IrpContext ); - - RtlZeroMemory( NewCcb, sizeof( CCB )); - - // - // Set the proper node type code and node byte size - // - - NewCcb->NodeTypeCode = CDFS_NTC_CCB; - NewCcb->NodeByteSize = sizeof( CCB ); - - // - // Set the initial value for the flags and Fcb - // - - NewCcb->Flags = Flags; - NewCcb->Fcb = Fcb; - - return NewCcb; -} - - -VOID -CdDeleteCcb ( - IN PIRP_CONTEXT IrpContext, - IN PCCB Ccb - ) -/*++ - -Routine Description: - - This routine is called to cleanup and deallocate a Ccb structure. - -Arguments: - - Ccb - This is the Ccb to delete. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - if (Ccb->SearchExpression.FileName.Buffer != NULL) { - - CdFreePool( &Ccb->SearchExpression.FileName.Buffer ); - } - - CdDeallocateCcb( IrpContext, Ccb ); - return; -} - - -BOOLEAN -CdCreateFileLock ( - IN PIRP_CONTEXT IrpContext OPTIONAL, - IN PFCB Fcb, - IN BOOLEAN RaiseOnError - ) - -/*++ - -Routine Description: - - This routine is called when we want to attach a file lock structure to the - given Fcb. It is possible the file lock is already attached. - - This routine is sometimes called from the fast path and sometimes in the - Irp-based path. We don't want to raise in the fast path, just return FALSE. - -Arguments: - - Fcb - This is the Fcb to create the file lock for. - - RaiseOnError - If TRUE, we will raise on an allocation failure. Otherwise we - return FALSE on an allocation failure. - -Return Value: - - BOOLEAN - TRUE if the Fcb has a filelock, FALSE otherwise. - ---*/ - -{ - BOOLEAN Result = TRUE; - PFILE_LOCK FileLock; - - PAGED_CODE(); - - // - // Lock the Fcb and check if there is really any work to do. - // - - CdLockFcb( IrpContext, Fcb ); - - if (Fcb->FileLock != NULL) { - - CdUnlockFcb( IrpContext, Fcb ); - return TRUE; - } - - Fcb->FileLock = FileLock = - FsRtlAllocateFileLock( NULL, NULL ); - - CdUnlockFcb( IrpContext, Fcb ); - - // - // Return or raise as appropriate. - // - - if (FileLock == NULL) { - - if (RaiseOnError) { - - ASSERT( ARGUMENT_PRESENT( IrpContext )); - - CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); - } - - Result = FALSE; - } - - return Result; -} - - -PIRP_CONTEXT -CdCreateIrpContext ( - IN PIRP Irp, - IN BOOLEAN Wait - ) - -/*++ - -Routine Description: - - This routine is called to initialize an IrpContext for the current - CDFS request. We allocate the structure and then initialize it from - the given Irp. - -Arguments: - - Irp - Irp for this request. - - Wait - TRUE if this request is synchronous, FALSE otherwise. - -Return Value: - - PIRP_CONTEXT - Allocated IrpContext. - ---*/ - -{ - PIRP_CONTEXT NewIrpContext = NULL; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - PAGED_CODE(); - - // - // The only operations a filesystem device object should ever receive - // are create/teardown of fsdo handles and operations which do not - // occur in the context of fileobjects (i.e., mount). - // - - if (IrpSp->DeviceObject == CdData.FileSystemDeviceObject) { - - if (IrpSp->FileObject != NULL && - IrpSp->MajorFunction != IRP_MJ_CREATE && - IrpSp->MajorFunction != IRP_MJ_CLEANUP && - IrpSp->MajorFunction != IRP_MJ_CLOSE) { - - ExRaiseStatus( STATUS_INVALID_DEVICE_REQUEST ); - } - - ASSERT( IrpSp->FileObject != NULL || - - (IrpSp->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL && - IrpSp->MinorFunction == IRP_MN_USER_FS_REQUEST && - IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_INVALIDATE_VOLUMES) || - - (IrpSp->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL && - IrpSp->MinorFunction == IRP_MN_MOUNT_VOLUME ) || - - IrpSp->MajorFunction == IRP_MJ_SHUTDOWN ); - } - - // - // Look in our lookaside list for an IrpContext. - // - - if (CdData.IrpContextDepth) { - - CdLockCdData(); - NewIrpContext = (PIRP_CONTEXT) PopEntryList( &CdData.IrpContextList ); - if (NewIrpContext != NULL) { - - CdData.IrpContextDepth--; - } - - CdUnlockCdData(); - } - - if (NewIrpContext == NULL) { - - // - // We didn't get it from our private list so allocate it from pool. - // - - NewIrpContext = FsRtlAllocatePoolWithTag( NonPagedPool, sizeof( IRP_CONTEXT ), TAG_IRP_CONTEXT ); - } - - RtlZeroMemory( NewIrpContext, sizeof( IRP_CONTEXT )); - - // - // Set the proper node type code and node byte size - // - - NewIrpContext->NodeTypeCode = CDFS_NTC_IRP_CONTEXT; - NewIrpContext->NodeByteSize = sizeof( IRP_CONTEXT ); - - // - // Set the originating Irp field - // - - NewIrpContext->Irp = Irp; - - // - // Copy RealDevice for workque algorithms. We will update this in the Mount or - // Verify since they have no file objects to use here. - // - - if (IrpSp->FileObject != NULL) { - - NewIrpContext->RealDevice = IrpSp->FileObject->DeviceObject; - } - - // - // Locate the volume device object and Vcb that we are trying to access. - // This may be our filesystem device object. In that case don't initialize - // the Vcb field. - // - - if (IrpSp->DeviceObject != CdData.FileSystemDeviceObject) { - - NewIrpContext->Vcb = &((PVOLUME_DEVICE_OBJECT) IrpSp->DeviceObject)->Vcb; - - } - - // - // Major/Minor Function codes - // - - NewIrpContext->MajorFunction = IrpSp->MajorFunction; - NewIrpContext->MinorFunction = IrpSp->MinorFunction; - - // - // Set the wait parameter - // - - if (Wait) { - - SetFlag( NewIrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); - - } else { - - SetFlag( NewIrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST ); - } - - // - // return and tell the caller - // - - return NewIrpContext; -} - - -VOID -CdCleanupIrpContext ( - IN PIRP_CONTEXT IrpContext, - IN BOOLEAN Post - ) - -/*++ - -Routine Description: - - This routine is called to cleanup and possibly deallocate the Irp Context. - If the request is being posted or this Irp Context is possibly on the - stack then we only cleanup any auxilary structures. - -Arguments: - - Post - TRUE if we are posting this request, FALSE if we are deleting - or retrying this in the current thread. - -Return Value: - - None. - ---*/ - -{ - PAGED_CODE(); - - // - // If we aren't doing more processing then deallocate this as appropriate. - // - - if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING)) { - - // - // If this context is the top level CDFS context then we need to - // restore the top level thread context. - // - - if (IrpContext->ThreadContext != NULL) { - - CdRestoreThreadContext( IrpContext ); - } - - // - // Deallocate the Io context if allocated. - // - - if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO )) { - - CdFreeIoContext( IrpContext->IoContext ); - } - - // - // Deallocate the IrpContext if not from the stack. - // - - if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ON_STACK )) { - - if (CdData.IrpContextDepth < CdData.IrpContextMaxDepth) { - - CdLockCdData(); - - PushEntryList( &CdData.IrpContextList, (PSINGLE_LIST_ENTRY) IrpContext ); - CdData.IrpContextDepth++; - - CdUnlockCdData(); - - } else { - - // - // We couldn't add this to our lookaside list so free it to - // pool. - // - - CdFreePool( &IrpContext ); - } - } - - // - // Clear the appropriate flags. - // - - } else if (Post) { - - // - // If this context is the top level CDFS context then we need to - // restore the top level thread context. - // - - if (IrpContext->ThreadContext != NULL) { - - CdRestoreThreadContext( IrpContext ); - } - - ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAGS_CLEAR_ON_POST ); - - } else { - - ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAGS_CLEAR_ON_RETRY ); - } - - return; -} - - -VOID -CdInitializeStackIrpContext ( - OUT PIRP_CONTEXT IrpContext, - IN PIRP_CONTEXT_LITE IrpContextLite - ) - -/*++ - -Routine Description: - - This routine is called to initialize an IrpContext for the current - CDFS request. The IrpContext is on the stack and we need to initialize - it for the current request. The request is a close operation. - -Arguments: - - IrpContext - IrpContext to initialize. - - IrpContextLite - Structure containing the details of this request. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // - // Zero and then initialize the structure. - // - - RtlZeroMemory( IrpContext, sizeof( IRP_CONTEXT )); - - // - // Set the proper node type code and node byte size - // - - IrpContext->NodeTypeCode = CDFS_NTC_IRP_CONTEXT; - IrpContext->NodeByteSize = sizeof( IRP_CONTEXT ); - - // - // Note that this is from the stack. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ON_STACK ); - - // - // Copy RealDevice for workque algorithms. - // - - IrpContext->RealDevice = IrpContextLite->RealDevice; - - // - // The Vcb is found in the Fcb. - // - - IrpContext->Vcb = IrpContextLite->Fcb->Vcb; - - // - // Major/Minor Function codes - // - - IrpContext->MajorFunction = IRP_MJ_CLOSE; - - // - // Set the wait parameter - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); - - return; -} - - -VOID -CdTeardownStructures ( - IN PIRP_CONTEXT IrpContext, - IN PFCB StartingFcb, - OUT PBOOLEAN RemovedStartingFcb - ) - -/*++ - -Routine Description: - - This routine is used to walk from some starting point in the Fcb tree towards - the root. It will remove the Fcb and continue walking up the tree until - it finds a point where we can't remove an Fcb. - - We look at the following fields in the Fcb to determine whether we can - remove this. - - 1 - Handle count must be zero. - 2 - If directory then only the only reference can be for a stream file. - 3 - Reference count must either be zero or go to zero here. - - We return immediately if we are recursively entering this routine. - -Arguments: - - StartingFcb - This is the Fcb node in the tree to begin with. This Fcb - must currently be acquired exclusively. - - RemovedStartingFcb - Address to store whether we removed the starting Fcb. - -Return Value: - - None - ---*/ - -{ - PVCB Vcb = StartingFcb->Vcb; - PFCB CurrentFcb = StartingFcb; - BOOLEAN AcquiredCurrentFcb = FALSE; - PFCB ParentFcb; - - PAGED_CODE(); - - *RemovedStartingFcb = FALSE; - - // - // If this is a recursive call to TearDownStructures we return immediately - // doing no operation. - // - - if (FlagOn( IrpContext->TopLevel->Flags, IRP_CONTEXT_FLAG_IN_TEARDOWN )) { - - return; - } - - SetFlag( IrpContext->TopLevel->Flags, IRP_CONTEXT_FLAG_IN_TEARDOWN ); - - // - // Use a try-finally to safely clear the top-level field. - // - - try { - - // - // Loop until we find an Fcb we can't remove. - // - - do { - - // - // See if there is an internal stream we should delete. - // Only do this if it is the last reference on the Fcb. - // - - if ((SafeNodeType( CurrentFcb ) != CDFS_NTC_FCB_DATA) && - (CurrentFcb->FcbUserReference == 0) && - (CurrentFcb->FileObject != NULL)) { - - // - // Go ahead and delete the stream file object. - // - - CdDeleteInternalStream( IrpContext, CurrentFcb ); - } - - // - // If the reference count is non-zero then break. - // - - if (CurrentFcb->FcbReference != 0) { - - break; - } - - // - // It looks like we have a candidate for removal here. We - // will need to acquire the parent, if present, in order to - // remove this from the parent prefix table. - // - - ParentFcb = CurrentFcb->ParentFcb; - - if (ParentFcb != NULL) { - - CdAcquireFcbExclusive( IrpContext, ParentFcb, FALSE ); - } - - // - // Now lock the vcb. - // - - CdLockVcb( IrpContext, Vcb ); - - // - // Final check to see if the reference count is still zero. - // - - if (CurrentFcb->FcbReference != 0) { - - CdUnlockVcb( IrpContext, Vcb ); - - if (ParentFcb != NULL) { - - CdReleaseFcb( IrpContext, ParentFcb ); - } - - break; - } - - // - // If there is a parent then do the necessary cleanup for the parent. - // - - if (ParentFcb != NULL) { - - CdRemovePrefix( IrpContext, CurrentFcb ); - RemoveEntryList( &CurrentFcb->FcbLinks ); - - CdDecrementReferenceCounts( IrpContext, ParentFcb, 1, 1 ); - } - - if (FlagOn( CurrentFcb->FcbState, FCB_STATE_IN_FCB_TABLE )) { - - CdDeleteFcbTable( IrpContext, CurrentFcb ); - ClearFlag( CurrentFcb->FcbState, FCB_STATE_IN_FCB_TABLE ); - - } - - // - // Unlock the Vcb but hold the parent in order to walk up - // the tree. - // - - CdUnlockVcb( IrpContext, Vcb ); - CdDeleteFcb( IrpContext, CurrentFcb ); - - // - // Move to the parent Fcb. - // - - CurrentFcb = ParentFcb; - AcquiredCurrentFcb = TRUE; - - } while (CurrentFcb != NULL); - - } finally { - - // - // Release the current Fcb if we have acquired it. - // - - if (AcquiredCurrentFcb && (CurrentFcb != NULL)) { - - CdReleaseFcb( IrpContext, CurrentFcb ); - } - - // - // Clear the teardown flag. - // - - ClearFlag( IrpContext->TopLevel->Flags, IRP_CONTEXT_FLAG_IN_TEARDOWN ); - } - - *RemovedStartingFcb = (CurrentFcb != StartingFcb); - return; -} - - -PFCB -CdLookupFcbTable ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN FILE_ID FileId - ) - -/*++ - -Routine Description: - - This routine will look through the Fcb table looking for a matching - entry. - -Arguments: - - Vcb - Vcb for this volume. - - FileId - This is the key value to use for the search. - -Return Value: - - PFCB - A pointer to the matching entry or NULL otherwise. - ---*/ - -{ - FCB_TABLE_ELEMENT Key; - PFCB_TABLE_ELEMENT Hit; - PFCB ReturnFcb = NULL; - - PAGED_CODE(); - - Key.FileId = FileId; - - Hit = (PFCB_TABLE_ELEMENT) RtlLookupElementGenericTable( &Vcb->FcbTable, &Key ); - - if (Hit != NULL) { - - ReturnFcb = Hit->Fcb; - } - - return ReturnFcb; - - UNREFERENCED_PARAMETER( IrpContext ); -} - - -PFCB -CdGetNextFcb ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PVOID *RestartKey - ) - -/*++ - -Routine Description: - - This routine will enumerate through all of the Fcb's in the Fcb table. - -Arguments: - - Vcb - Vcb for this volume. - - RestartKey - This value is used by the table package to maintain - its position in the enumeration. It is initialized to NULL - for the first search. - -Return Value: - - PFCB - A pointer to the next fcb or NULL if the enumeration is - completed - ---*/ - -{ - PFCB Fcb; - - PAGED_CODE(); - - Fcb = (PFCB) RtlEnumerateGenericTableWithoutSplaying( &Vcb->FcbTable, RestartKey ); - - if (Fcb != NULL) { - - Fcb = ((PFCB_TABLE_ELEMENT)(Fcb))->Fcb; - } - - return Fcb; -} - - -NTSTATUS -CdProcessToc ( - IN PIRP_CONTEXT IrpContext, - IN PDEVICE_OBJECT TargetDeviceObject, - IN PCDROM_TOC CdromToc, - IN OUT PULONG Length, - OUT PULONG TrackCount, - OUT PULONG DiskFlags - ) - -/*++ - -Routine Description: - - This routine is called to verify and process the TOC for this disk. - We hide a data track for a CD+ volume. - -Arguments: - - TargetDeviceObject - Device object to send TOC request to. - - CdromToc - Pointer to TOC structure. - - Length - On input this is the length of the TOC. On return is the TOC - length we will show to the user. - - TrackCount - This is the count of tracks for the TOC. We use this - when creating a pseudo directory for a music disk. - - DiskFlags - We return flags indicating what we know about this disk. - -Return Value: - - NTSTATUS - The result of trying to read the TOC. - ---*/ - -{ - NTSTATUS Status; - IO_STATUS_BLOCK Iosb; - - ULONG CurrentTrack; - ULONG LocalTrackCount; - ULONG LocalTocLength; - - union { - - UCHAR BigEndian[2]; - USHORT Length; - - } BiasedTocLength; - - PTRACK_DATA Track; - - PAGED_CODE(); - - // - // Go ahead and read the table of contents - // - - Status = CdPerformDevIoCtrl( IrpContext, - IOCTL_CDROM_READ_TOC, - TargetDeviceObject, - CdromToc, - sizeof( CDROM_TOC ), - FALSE, - TRUE, - &Iosb ); - - // - // Nothing to process if this request fails. - // - - if (Status != STATUS_SUCCESS) { - - return Status; - } - - // - // Get the number of tracks and stated size of this structure. - // - - CurrentTrack = 0; - LocalTrackCount = CdromToc->LastTrack - CdromToc->FirstTrack + 1; - LocalTocLength = PtrOffset( CdromToc, &CdromToc->TrackData[LocalTrackCount + 1] ); - - // - // Get out if there is an immediate problem with the TOC. - // - - if ((LocalTocLength > Iosb.Information) || - (CdromToc->FirstTrack > CdromToc->LastTrack)) { - - Status = STATUS_DISK_CORRUPT_ERROR; - return Status; - } - - // - // Walk through the individual tracks. Stop at the first data track after - // any lead-in audio tracks. - // - - do { - - // - // Get the next track. - // - - Track = &CdromToc->TrackData[CurrentTrack]; - - // - // If this is a data track then check if we have only seen audio tracks - // to this point. - // - - if (FlagOn( Track->Control, TOC_DATA_TRACK )) { - - // - // If we have only seen audio tracks then assume this is a - // CD+ disk. Hide the current data track and only return - // the previous audio tracks. Set the disk type to be mixed - // data/audio. - // - - if (FlagOn( *DiskFlags, CDROM_DISK_AUDIO_TRACK ) && - !FlagOn( *DiskFlags, CDROM_DISK_DATA_TRACK )) { - - // - // Remove one track from the TOC. - // - - CdromToc->LastTrack -= 1; - - // - // Knock 2.5 minutes off the current track to - // hide the final leadin. - // - - Track->Address[1] -= 2; - Track->Address[2] += 30; - - if (Track->Address[2] < 60) { - - Track->Address[1] -= 1; - - } else { - - Track->Address[2] -= 60; - } - - Track->TrackNumber = TOC_LAST_TRACK; - - // - // Set the disk type to mixed data/audio. - // - - SetFlag( *DiskFlags, CDROM_DISK_DATA_TRACK ); - - break; - } - - // - // Set the flag to indicate data tracks present. - // - - SetFlag( *DiskFlags, CDROM_DISK_DATA_TRACK ); - - // - // If this is a audio track then set the flag indicating audio - // tracks. - // - - } else { - - SetFlag( *DiskFlags, CDROM_DISK_AUDIO_TRACK ); - } - - // - // Set our index for the next track. - // - - CurrentTrack += 1; - - } while (CurrentTrack < LocalTrackCount); - - // - // Set the length to point just past the last track we looked at. - // - - *TrackCount = CurrentTrack; - *Length = PtrOffset( CdromToc, &CdromToc->TrackData[CurrentTrack + 1] ); - BiasedTocLength.Length = (USHORT) *Length - 2; - - CdromToc->Length[0] = BiasedTocLength.BigEndian[1]; - CdromToc->Length[1] = BiasedTocLength.BigEndian[0]; - - return Status; -} - - -// -// Local support routine -// - -VOID -CdDeleteFcb ( - IN PIRP_CONTEXT IrpContext, - IN PFCB Fcb - ) - -/*++ - -Routine Description: - - This routine is called to cleanup and deallocate an Fcb. We know there - are no references remaining. We cleanup any auxilary structures and - deallocate this Fcb. - -Arguments: - - Fcb - This is the Fcb to deallcoate. - -Return Value: - - None - ---*/ - -{ - PVCB Vcb = NULL; - PAGED_CODE(); - - // - // Sanity check the counts. - // - - ASSERT( Fcb->FcbCleanup == 0 ); - ASSERT( Fcb->FcbReference == 0 ); - - // - // Release any Filter Context structures associated with this FCB - // - - FsRtlTeardownPerStreamContexts( &Fcb->Header ); - - // - // Start with the common structures. - // - - CdUninitializeMcb( IrpContext, Fcb ); - - CdDeleteFcbNonpaged( IrpContext, Fcb->FcbNonpaged ); - - // - // Check if we need to deallocate the prefix name buffer. - // - - if ((Fcb->FileNamePrefix.ExactCaseName.FileName.Buffer != (PWCHAR) Fcb->FileNamePrefix.FileNameBuffer) && - (Fcb->FileNamePrefix.ExactCaseName.FileName.Buffer != NULL)) { - - CdFreePool( &Fcb->FileNamePrefix.ExactCaseName.FileName.Buffer ); - } - - // - // Now look at the short name prefix. - // - - if (Fcb->ShortNamePrefix != NULL) { - - CdFreePool( &Fcb->ShortNamePrefix ); - } - - // - // Now do the type specific structures. - // - - switch (Fcb->NodeTypeCode) { - - case CDFS_NTC_FCB_PATH_TABLE: - case CDFS_NTC_FCB_INDEX: - - ASSERT( Fcb->FileObject == NULL ); - ASSERT( IsListEmpty( &Fcb->FcbQueue )); - - if (Fcb == Fcb->Vcb->RootIndexFcb) { - - Vcb = Fcb->Vcb; - Vcb->RootIndexFcb = NULL; - - } else if (Fcb == Fcb->Vcb->PathTableFcb) { - - Vcb = Fcb->Vcb; - Vcb->PathTableFcb = NULL; - } - - CdDeallocateFcbIndex( IrpContext, Fcb ); - break; - - case CDFS_NTC_FCB_DATA : - - if (Fcb->FileLock != NULL) { - - FsRtlFreeFileLock( Fcb->FileLock ); - } - - FsRtlUninitializeOplock( &Fcb->Oplock ); - - if (Fcb == Fcb->Vcb->VolumeDasdFcb) { - - Vcb = Fcb->Vcb; - Vcb->VolumeDasdFcb = NULL; - } - - CdDeallocateFcbData( IrpContext, Fcb ); - } - - // - // Decrement the Vcb reference count if this is a system - // Fcb. - // - - if (Vcb != NULL) { - - InterlockedDecrement( &Vcb->VcbReference ); - InterlockedDecrement( &Vcb->VcbUserReference ); - } - - return; -} - - -// -// Local support routine -// - -PFCB_NONPAGED -CdCreateFcbNonpaged ( - IN PIRP_CONTEXT IrpContext - ) - -/*++ - -Routine Description: - - This routine is called to create and initialize the non-paged portion - of an Fcb. - -Arguments: - -Return Value: - - PFCB_NONPAGED - Pointer to the created nonpaged Fcb. NULL if not created. - ---*/ - -{ - PFCB_NONPAGED FcbNonpaged; - - PAGED_CODE(); - - // - // Allocate the non-paged pool and initialize the various - // synchronization objects. - // - - FcbNonpaged = CdAllocateFcbNonpaged( IrpContext ); - - if (FcbNonpaged != NULL) { - - RtlZeroMemory( FcbNonpaged, sizeof( FCB_NONPAGED )); - - FcbNonpaged->NodeTypeCode = CDFS_NTC_FCB_NONPAGED; - FcbNonpaged->NodeByteSize = sizeof( FCB_NONPAGED ); - - ExInitializeResourceLite( &FcbNonpaged->FcbResource ); - ExInitializeFastMutex( &FcbNonpaged->FcbMutex ); - } - - return FcbNonpaged; -} - - -// -// Local support routine -// - -VOID -CdDeleteFcbNonpaged ( - IN PIRP_CONTEXT IrpContext, - IN PFCB_NONPAGED FcbNonpaged - ) - -/*++ - -Routine Description: - - This routine is called to cleanup the non-paged portion of an Fcb. - -Arguments: - - FcbNonpaged - Structure to clean up. - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - ExDeleteResourceLite( &FcbNonpaged->FcbResource ); - - CdDeallocateFcbNonpaged( IrpContext, FcbNonpaged ); - - return; -} - - -// -// Local support routine -// - -RTL_GENERIC_COMPARE_RESULTS -CdFcbTableCompare ( - IN PRTL_GENERIC_TABLE FcbTable, - IN PVOID Fid1, - IN PVOID Fid2 - ) - -/*++ - -Routine Description: - - This routine is the Cdfs compare routine called by the generic table package. - If will compare the two File Id values and return a comparison result. - -Arguments: - - FcbTable - This is the table being searched. - - Fid1 - First key value. - - Fid2 - Second key value. - -Return Value: - - RTL_GENERIC_COMPARE_RESULTS - The results of comparing the two - input structures - ---*/ - -{ - FILE_ID Id1, Id2; - PAGED_CODE(); - - Id1 = *((FILE_ID UNALIGNED *) Fid1); - Id2 = *((FILE_ID UNALIGNED *) Fid2); - - if (Id1.QuadPart < Id2.QuadPart) { - - return GenericLessThan; - - } else if (Id1.QuadPart > Id2.QuadPart) { - - return GenericGreaterThan; - - } else { - - return GenericEqual; - } - - UNREFERENCED_PARAMETER( FcbTable ); -} - - -// -// Local support routine -// - -PVOID -CdAllocateFcbTable ( - IN PRTL_GENERIC_TABLE FcbTable, - IN CLONG ByteSize - ) - -/*++ - -Routine Description: - - This is a generic table support routine to allocate memory - -Arguments: - - FcbTable - Supplies the generic table being used - - ByteSize - Supplies the number of bytes to allocate - -Return Value: - - PVOID - Returns a pointer to the allocated data - ---*/ - -{ - PAGED_CODE(); - - return( FsRtlAllocatePoolWithTag( CdPagedPool, ByteSize, TAG_FCB_TABLE )); -} - - -// -// Local support routine -// - -VOID -CdDeallocateFcbTable ( - IN PRTL_GENERIC_TABLE FcbTable, - IN PVOID Buffer - ) - -/*++ - -Routine Description: - - This is a generic table support routine that deallocates memory - -Arguments: - - FcbTable - Supplies the generic table being used - - Buffer - Supplies the buffer being deallocated - -Return Value: - - None. - ---*/ - -{ - PAGED_CODE(); - - CdFreePool( &Buffer ); - - UNREFERENCED_PARAMETER( FcbTable ); -} - - -// -// Local support routine -// - -ULONG -CdTocSerial ( - IN PIRP_CONTEXT IrpContext, - IN PCDROM_TOC CdromToc - ) - -/*++ - -Routine Description: - - This routine is called to generate a serial number for an audio disk. - The number is based on the starting positions of the tracks. - The following algorithm is used. - - If the number of tracks is <= 2 then initialize the serial number to the - leadout block number. - - Then add the starting address of each track (use 0x00mmssff format). - -Arguments: - - CdromToc - Valid table of contents to use for track information. - -Return Value: - - ULONG - 32 bit serial number based on TOC. - ---*/ - -{ - ULONG SerialNumber = 0; - PTRACK_DATA ThisTrack; - PTRACK_DATA LastTrack; - - PAGED_CODE(); - - // - // Check if there are two tracks or fewer. - // - - LastTrack = &CdromToc->TrackData[ CdromToc->LastTrack - CdromToc->FirstTrack + 1]; - ThisTrack = &CdromToc->TrackData[0]; - - if (CdromToc->LastTrack - CdromToc->FirstTrack <= 1) { - - SerialNumber = (((LastTrack->Address[1] * 60) + LastTrack->Address[2]) * 75) + LastTrack->Address[3]; - - SerialNumber -= (((ThisTrack->Address[1] * 60) + ThisTrack->Address[2]) * 75) + ThisTrack->Address[3]; - } - - // - // Now find the starting offset of each track and add to the serial number. - // - - while (ThisTrack != LastTrack) { - - SerialNumber += (ThisTrack->Address[1] << 16); - SerialNumber += (ThisTrack->Address[2] << 8); - SerialNumber += ThisTrack->Address[3]; - ThisTrack += 1; - } - - return SerialNumber; -} - - diff --git a/reactos/drivers/filesystems/cdfs_new/verfysup.c b/reactos/drivers/filesystems/cdfs_new/verfysup.c deleted file mode 100755 index 612c867248f..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/verfysup.c +++ /dev/null @@ -1,957 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - VerfySup.c - -Abstract: - - This module implements the Cdfs Verification routines. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_VERFYSUP) - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdVerifyFcbOperation) -#pragma alloc_text(PAGE, CdVerifyVcb) -#endif - - -NTSTATUS -CdPerformVerify ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp, - IN PDEVICE_OBJECT DeviceToVerify - ) - -/*++ - -Routine Description: - - This routines performs an IoVerifyVolume operation and takes the - appropriate action. If the verify is successful then we send the originating - Irp off to an Ex Worker Thread. This routine is called from the exception handler. - - No file system resources are held when this routine is called. - -Arguments: - - Irp - The irp to send off after all is well and done. - - Device - The real device needing verification. - -Return Value: - - None. - ---*/ - -{ - PVCB Vcb; - NTSTATUS Status = STATUS_SUCCESS; - PIO_STACK_LOCATION IrpSp; - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_IRP( Irp ); - - // - // Check if this Irp has a status of Verify required and if it does - // then call the I/O system to do a verify. - // - // Skip the IoVerifyVolume if this is a mount or verify request - // itself. Trying a recursive mount will cause a deadlock with - // the DeviceObject->DeviceLock. - // - - if ((IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) && - ((IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) || - (IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME))) { - - return CdFsdPostRequest( IrpContext, Irp ); - } - - // - // Extract a pointer to the Vcb from the VolumeDeviceObject. - // Note that since we have specifically excluded mount, - // requests, we know that IrpSp->DeviceObject is indeed a - // volume device object. - // - - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - Vcb = &CONTAINING_RECORD( IrpSp->DeviceObject, - VOLUME_DEVICE_OBJECT, - DeviceObject )->Vcb; - try { - - // - // Send down the verify FSCTL. Note that this is sent to the - // currently mounted volume, which may not be this one. - // - // We will allow Raw to mount this volume if we were doing a - // an absolute DASD open. - // - - Status = IoVerifyVolume( DeviceToVerify, CdOperationIsDasdOpen( IrpContext)); - - // - // Acquire the Vcb so we're working with a stable VcbCondition. - // - - CdAcquireVcbShared( IrpContext, Vcb, FALSE); - - // - // If the verify operation completed it will return - // either STATUS_SUCCESS or STATUS_WRONG_VOLUME, exactly. - // - // If CdVerifyVolume encountered an error during - // processing, it will return that error. If we got - // STATUS_WRONG_VOLUME from the verify, and our volume - // is now mounted, commute the status to STATUS_SUCCESS. - // - - if ((Status == STATUS_WRONG_VOLUME) && - (Vcb->VcbCondition == VcbMounted)) { - - Status = STATUS_SUCCESS; - } - else if ((STATUS_SUCCESS == Status) && (Vcb->VcbCondition != VcbMounted)) { - - // - // If the verify succeeded, but our volume is not mounted, - // then some other volume is on the device. - // - - Status = STATUS_WRONG_VOLUME; - } - - // - // Do a quick unprotected check here. The routine will do - // a safe check. After here we can release the resource. - // Note that if the volume really went away, we will be taking - // the Reparse path. - // - - // - // If the device might need to go away then call our dismount routine. - // - - if (((Vcb->VcbCondition == VcbNotMounted) || - (Vcb->VcbCondition == VcbInvalid) || - (Vcb->VcbCondition == VcbDismountInProgress)) && - (Vcb->VcbReference <= CDFS_RESIDUAL_REFERENCE)) { - - CdReleaseVcb( IrpContext, Vcb); - - CdAcquireCdData( IrpContext ); - CdCheckForDismount( IrpContext, Vcb, FALSE ); - CdReleaseCdData( IrpContext ); - } - else { - - CdReleaseVcb( IrpContext, Vcb); - } - - // - // If this is a create and the verify succeeded then complete the - // request with a REPARSE status. - // - - if ((IrpContext->MajorFunction == IRP_MJ_CREATE) && - (IrpSp->FileObject->RelatedFileObject == NULL) && - ((Status == STATUS_SUCCESS) || (Status == STATUS_WRONG_VOLUME))) { - - Irp->IoStatus.Information = IO_REMOUNT; - - CdCompleteRequest( IrpContext, Irp, STATUS_REPARSE ); - Status = STATUS_REPARSE; - Irp = NULL; - IrpContext = NULL; - - // - // If there is still an error to process then call the Io system - // for a popup. - // - - } else if ((Irp != NULL) && !NT_SUCCESS( Status )) { - - // - // Fill in the device object if required. - // - - if (IoIsErrorUserInduced( Status ) ) { - - IoSetHardErrorOrVerifyDevice( Irp, DeviceToVerify ); - } - - CdNormalizeAndRaiseStatus( IrpContext, Status ); - } - - // - // If there is still an Irp, send it off to an Ex Worker thread. - // - - if (IrpContext != NULL) { - - Status = CdFsdPostRequest( IrpContext, Irp ); - } - - } except(CdExceptionFilter( IrpContext, GetExceptionInformation() )) { - - // - // We had some trouble trying to perform the verify or raised - // an error ourselves. So we'll abort the I/O request with - // the error status that we get back from the execption code. - // - - Status = CdProcessException( IrpContext, Irp, GetExceptionCode() ); - } - - return Status; -} - - -BOOLEAN -CdCheckForDismount ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN BOOLEAN Force - ) - -/*++ - -Routine Description: - - This routine is called to check if a volume is ready for dismount. This - occurs when only file system references are left on the volume. - - If the dismount is not currently underway and the user reference count - has gone to zero then we can begin the dismount. - - If the dismount is in progress and there are no references left on the - volume (we check the Vpb for outstanding references as well to catch - any create calls dispatched to the file system) then we can delete - the Vcb. - -Arguments: - - Vcb - Vcb for the volume to try to dismount. - - Force - Whether we will force this volume to be dismounted. - -Return Value: - - BOOLEAN - True if the Vcb was not gone by the time this function finished, - False if it was deleted. - - This is only a trustworthy indication to the caller if it had the vcb - exclusive itself. - ---*/ - -{ - BOOLEAN UnlockVcb = TRUE; - BOOLEAN VcbPresent = TRUE; - KIRQL SavedIrql; - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_VCB( Vcb ); - - ASSERT_EXCLUSIVE_CDDATA; - - // - // Acquire and lock this Vcb to check the dismount state. - // - - CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); - - // - // Lets get rid of any pending closes for this volume. - // - - CdFspClose( Vcb ); - - CdLockVcb( IrpContext, Vcb ); - - // - // If the dismount is not already underway then check if the - // user reference count has gone to zero or we are being forced - // to disconnect. If so start the teardown on the Vcb. - // - - if (Vcb->VcbCondition != VcbDismountInProgress) { - - if (Vcb->VcbUserReference <= CDFS_RESIDUAL_USER_REFERENCE || Force) { - - CdUnlockVcb( IrpContext, Vcb ); - UnlockVcb = FALSE; - VcbPresent = CdDismountVcb( IrpContext, Vcb ); - } - - // - // If the teardown is underway and there are absolutely no references - // remaining then delete the Vcb. References here include the - // references in the Vcb and Vpb. - // - - } else if (Vcb->VcbReference == 0) { - - IoAcquireVpbSpinLock( &SavedIrql ); - - // - // If there are no file objects and no reference counts in the - // Vpb we can delete the Vcb. Don't forget that we have the - // last reference in the Vpb. - // - - if (Vcb->Vpb->ReferenceCount == 1) { - - IoReleaseVpbSpinLock( SavedIrql ); - CdUnlockVcb( IrpContext, Vcb ); - UnlockVcb = FALSE; - CdDeleteVcb( IrpContext, Vcb ); - VcbPresent = FALSE; - - } else { - - IoReleaseVpbSpinLock( SavedIrql ); - } - } - - // - // Unlock the Vcb if still held. - // - - if (UnlockVcb) { - - CdUnlockVcb( IrpContext, Vcb ); - } - - // - // Release any resources still acquired. - // - - if (VcbPresent) { - - CdReleaseVcb( IrpContext, Vcb ); - } - - return VcbPresent; -} - - -BOOLEAN -CdMarkDevForVerifyIfVcbMounted( - IN PVCB Vcb - ) - -/*++ - -Routine Description: - - This routine checks to see if the specified Vcb is currently mounted on - the device or not. If it is, it sets the verify flag on the device, if - not then the state is noted in the Vcb. - -Arguments: - - Vcb - This is the volume to check. - -Return Value: - - TRUE if the device has been marked for verify here, FALSE otherwise. - ---*/ - -{ - BOOLEAN Marked = FALSE; - KIRQL SavedIrql; - - IoAcquireVpbSpinLock( &SavedIrql ); - - if (Vcb->Vpb->RealDevice->Vpb == Vcb->Vpb) { - - CdMarkRealDevForVerify( Vcb->Vpb->RealDevice); - Marked = TRUE; - } - else { - - // - // Flag this to avoid the VPB spinlock in future passes. - // - - SetFlag( Vcb->VcbState, VCB_STATE_VPB_NOT_ON_DEVICE); - } - - IoReleaseVpbSpinLock( SavedIrql ); - - return Marked; -} - - -VOID -CdVerifyVcb ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb - ) - -/*++ - -Routine Description: - - This routine checks that the current Vcb is valid and currently mounted - on the device. It will raise on an error condition. - - We check whether the volume needs verification and the current state - of the Vcb. - -Arguments: - - Vcb - This is the volume to verify. - -Return Value: - - None - ---*/ - -{ - NTSTATUS Status = STATUS_SUCCESS; - IO_STATUS_BLOCK Iosb; - ULONG MediaChangeCount = 0; - BOOLEAN ForceVerify = FALSE; - BOOLEAN DevMarkedForVerify; - //KIRQL SavedIrql; /* ReactOS Change: GCC Unused variable */ - - PAGED_CODE(); - - // - // Fail immediately if the volume is in the progress of being dismounted - // or has been marked invalid. - // - - if ((Vcb->VcbCondition == VcbInvalid) || - ((Vcb->VcbCondition == VcbDismountInProgress) && - (IrpContext->MajorFunction != IRP_MJ_CREATE))) { - - CdRaiseStatus( IrpContext, STATUS_FILE_INVALID ); - } - - if (FlagOn( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA )) { - - // - // Capture the real device verify state. - // - - DevMarkedForVerify = CdRealDevNeedsVerify( Vcb->Vpb->RealDevice); - - // - // If the media is removable and the verify volume flag in the - // device object is not set then we want to ping the device - // to see if it needs to be verified. - // - - if (Vcb->VcbCondition != VcbMountInProgress) { - - Status = CdPerformDevIoCtrl( IrpContext, - IOCTL_CDROM_CHECK_VERIFY, - Vcb->TargetDeviceObject, - &MediaChangeCount, - sizeof(ULONG), - FALSE, - FALSE, - &Iosb ); - - if (Iosb.Information != sizeof(ULONG)) { - - // - // Be safe about the count in case the driver didn't fill it in - // - - MediaChangeCount = 0; - } - - // - // There are four cases when we want to do a verify. These are the - // first three. - // - // 1. We are mounted, and the device has become empty - // 2. The device has returned verify required (=> DO_VERIFY_VOL flag is - // set, but could be due to hardware condition) - // 3. Media change count doesn't match the one in the Vcb - // - - if (((Vcb->VcbCondition == VcbMounted) && - CdIsRawDevice( IrpContext, Status )) - || - (Status == STATUS_VERIFY_REQUIRED) - || - (NT_SUCCESS(Status) && - (Vcb->MediaChangeCount != MediaChangeCount))) { - - // - // If we are currently the volume on the device then it is our - // responsibility to set the verify flag. If we're not on the device, - // then we shouldn't touch the flag. - // - - if (!FlagOn( Vcb->VcbState, VCB_STATE_VPB_NOT_ON_DEVICE) && - !DevMarkedForVerify) { - - DevMarkedForVerify = CdMarkDevForVerifyIfVcbMounted( Vcb); - } - - ForceVerify = TRUE; - - // - // NOTE that we no longer update the media change count here. We - // do so only when we've actually completed a verify at a particular - // change count value. - // - } - } - - // - // This is the 4th verify case. - // - // We ALWAYS force CREATE requests on unmounted volumes through the - // verify path. These requests could have been in limbo between - // IoCheckMountedVpb and us when a verify/mount took place and caused - // a completely different fs/volume to be mounted. In this case the - // checks above may not have caught the condition, since we may already - // have verified (wrong volume) and decided that we have nothing to do. - // We want the requests to be re routed to the currently mounted volume, - // since they were directed at the 'drive', not our volume. - // - - if (NT_SUCCESS( Status) && !ForceVerify && - (IrpContext->MajorFunction == IRP_MJ_CREATE)) { - - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->Irp); - - ForceVerify = (IrpSp->FileObject->RelatedFileObject == NULL) && - ((Vcb->VcbCondition == VcbDismountInProgress) || - (Vcb->VcbCondition == VcbNotMounted)); - - // - // Note that we don't touch the device verify flag here. It required - // it would have been caught and set by the first set of checks. - // - } - - // - // Raise the verify / error if neccessary. - // - - if (ForceVerify || !NT_SUCCESS( Status)) { - - IoSetHardErrorOrVerifyDevice( IrpContext->Irp, - Vcb->Vpb->RealDevice ); - - CdRaiseStatus( IrpContext, ForceVerify ? STATUS_VERIFY_REQUIRED : Status); - } - } - - // - // Based on the condition of the Vcb we'll either return to our - // caller or raise an error condition - // - - switch (Vcb->VcbCondition) { - - case VcbNotMounted: - - IoSetHardErrorOrVerifyDevice( IrpContext->Irp, Vcb->Vpb->RealDevice ); - - CdRaiseStatus( IrpContext, STATUS_WRONG_VOLUME ); - break; - - case VcbInvalid: - case VcbDismountInProgress : - - CdRaiseStatus( IrpContext, STATUS_FILE_INVALID ); - break; - - /* ReactOS Change: GCC "enumeration value not handled in switch" */ - default: break; - } -} - - -BOOLEAN -CdVerifyFcbOperation ( - IN PIRP_CONTEXT IrpContext OPTIONAL, - IN PFCB Fcb - ) - -/*++ - -Routine Description: - - This routine is called to verify that the state of the Fcb is valid - to allow the current operation to continue. We use the state of the - Vcb, target device and type of operation to determine this. - -Arguments: - - IrpContext - IrpContext for the request. If not present then we - were called from the fast IO path. - - Fcb - Fcb to perform the request on. - -Return Value: - - BOOLEAN - TRUE if the request can continue, FALSE otherwise. - ---*/ - -{ - //NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC Unused variable */ - PVCB Vcb = Fcb->Vcb; - PDEVICE_OBJECT RealDevice = Vcb->Vpb->RealDevice; - PIRP Irp; - - PAGED_CODE(); - - // - // Check that the fileobject has not been cleaned up. - // - - if ( ARGUMENT_PRESENT( IrpContext )) { - - PFILE_OBJECT FileObject; - - Irp = IrpContext->Irp; - FileObject = IoGetCurrentIrpStackLocation( Irp)->FileObject; - - if ( FileObject && FlagOn( FileObject->Flags, FO_CLEANUP_COMPLETE)) { - - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - // - // Following FAT, we allow certain operations even on cleaned up - // file objects. Everything else, we fail. - // - - if ( (FlagOn(Irp->Flags, IRP_PAGING_IO)) || - (IrpSp->MajorFunction == IRP_MJ_CLOSE ) || - (IrpSp->MajorFunction == IRP_MJ_QUERY_INFORMATION) || - ( (IrpSp->MajorFunction == IRP_MJ_READ) && - FlagOn(IrpSp->MinorFunction, IRP_MN_COMPLETE) ) ) { - - NOTHING; - - } else { - - CdRaiseStatus( IrpContext, STATUS_FILE_CLOSED ); - } - } - } - - // - // Fail immediately if the volume is in the progress of being dismounted - // or has been marked invalid. - // - - if ((Vcb->VcbCondition == VcbInvalid) || - (Vcb->VcbCondition == VcbDismountInProgress)) { - - if (ARGUMENT_PRESENT( IrpContext )) { - - CdRaiseStatus( IrpContext, STATUS_FILE_INVALID ); - } - - return FALSE; - } - - // - // Always fail if the volume needs to be verified. - // - - if (CdRealDevNeedsVerify( RealDevice)) { - - if (ARGUMENT_PRESENT( IrpContext )) { - - IoSetHardErrorOrVerifyDevice( IrpContext->Irp, - RealDevice ); - - CdRaiseStatus( IrpContext, STATUS_VERIFY_REQUIRED ); - } - - return FALSE; - - // - // - // All operations are allowed on mounted. - // - - } else if ((Vcb->VcbCondition == VcbMounted) || - (Vcb->VcbCondition == VcbMountInProgress)) { - - return TRUE; - - // - // Fail all requests for fast Io on other Vcb conditions. - // - - } else if (!ARGUMENT_PRESENT( IrpContext )) { - - return FALSE; - - // - // The remaining case is VcbNotMounted. - // Mark the device to be verified and raise WRONG_VOLUME. - // - - } else if (Vcb->VcbCondition == VcbNotMounted) { - - if (ARGUMENT_PRESENT( IrpContext )) { - - IoSetHardErrorOrVerifyDevice( IrpContext->Irp, RealDevice ); - CdRaiseStatus( IrpContext, STATUS_WRONG_VOLUME ); - } - - return FALSE; - } - - return TRUE; -} - - -BOOLEAN -CdDismountVcb ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb - ) - -/*++ - -Routine Description: - - This routine is called when all of the user references to a volume are - gone. We will initiate all of the teardown any system resources. - - If all of the references to this volume are gone at the end of this routine - then we will complete the teardown of this Vcb and mark the current Vpb - as not mounted. Otherwise we will allocated a new Vpb for this device - and keep the current Vpb attached to the Vcb. - -Arguments: - - Vcb - Vcb for the volume to dismount. - -Return Value: - - BOOLEAN - TRUE if we didn't delete the Vcb, FALSE otherwise. - ---*/ - -{ - PVPB OldVpb; - BOOLEAN VcbPresent = TRUE; - KIRQL SavedIrql; - - BOOLEAN FinalReference; - - ASSERT_EXCLUSIVE_CDDATA; - ASSERT_EXCLUSIVE_VCB( Vcb ); - - CdLockVcb( IrpContext, Vcb ); - - // - // We should only take this path once. - // - - ASSERT( Vcb->VcbCondition != VcbDismountInProgress ); - - // - // Mark the Vcb as DismountInProgress. - // - - Vcb->VcbCondition = VcbDismountInProgress; - - if (Vcb->XASector != NULL) { - - CdFreePool( &Vcb->XASector ); - Vcb->XASector = 0; - Vcb->XADiskOffset = 0; - } - - // - // Remove our reference to the internal Fcb's. The Fcb's will then - // be removed in the purge path below. - // - - if (Vcb->RootIndexFcb != NULL) { - - Vcb->RootIndexFcb->FcbReference -= 1; - Vcb->RootIndexFcb->FcbUserReference -= 1; - } - - if (Vcb->PathTableFcb != NULL) { - - Vcb->PathTableFcb->FcbReference -= 1; - Vcb->PathTableFcb->FcbUserReference -= 1; - } - - if (Vcb->VolumeDasdFcb != NULL) { - - Vcb->VolumeDasdFcb->FcbReference -= 1; - Vcb->VolumeDasdFcb->FcbUserReference -= 1; - } - - CdUnlockVcb( IrpContext, Vcb ); - - // - // Purge the volume. - // - - CdPurgeVolume( IrpContext, Vcb, TRUE ); - - // - // Empty the delayed and async close queues. - // - - CdFspClose( Vcb ); - - OldVpb = Vcb->Vpb; - - // - // Remove the mount volume reference. - // - - CdLockVcb( IrpContext, Vcb ); - Vcb->VcbReference -= 1; - - // - // Acquire the Vpb spinlock to check for Vpb references. - // - - IoAcquireVpbSpinLock( &SavedIrql ); - - // - // Remember if this is the last reference on this Vcb. We incremented - // the count on the Vpb earlier so we get one last crack it. If our - // reference has gone to zero but the vpb reference count is greater - // than zero then the Io system will be responsible for deleting the - // Vpb. - // - - FinalReference = (BOOLEAN) ((Vcb->VcbReference == 0) && - (OldVpb->ReferenceCount == 1)); - - // - // There is a reference count in the Vpb and in the Vcb. We have - // incremented the reference count in the Vpb to make sure that - // we have last crack at it. If this is a failed mount then we - // want to return the Vpb to the IO system to use for the next - // mount request. - // - - if (OldVpb->RealDevice->Vpb == OldVpb) { - - // - // If not the final reference then swap out the Vpb. We must - // preserve the REMOVE_PENDING flag so that the device is - // not remounted in the middle of a PnP remove operation. - // - - if (!FinalReference) { - - ASSERT( Vcb->SwapVpb != NULL ); - - Vcb->SwapVpb->Type = IO_TYPE_VPB; - Vcb->SwapVpb->Size = sizeof( VPB ); - Vcb->SwapVpb->RealDevice = OldVpb->RealDevice; - - Vcb->SwapVpb->RealDevice->Vpb = Vcb->SwapVpb; - - Vcb->SwapVpb->Flags = FlagOn( OldVpb->Flags, VPB_REMOVE_PENDING ); - - IoReleaseVpbSpinLock( SavedIrql ); - - // - // Indicate we used up the swap. - // - - Vcb->SwapVpb = NULL; - - CdUnlockVcb( IrpContext, Vcb ); - - // - // We want to leave the Vpb for the IO system. Mark it - // as being not mounted. Go ahead and delete the Vcb as - // well. - // - - } else { - - // - // Make sure to remove the last reference on the Vpb. - // - - OldVpb->ReferenceCount -= 1; - - OldVpb->DeviceObject = NULL; - ClearFlag( Vcb->Vpb->Flags, VPB_MOUNTED ); - ClearFlag( Vcb->Vpb->Flags, VPB_LOCKED ); - - // - // Clear the Vpb flag so we know not to delete it. - // - - Vcb->Vpb = NULL; - - IoReleaseVpbSpinLock( SavedIrql ); - CdUnlockVcb( IrpContext, Vcb ); - CdDeleteVcb( IrpContext, Vcb ); - VcbPresent = FALSE; - } - - // - // Someone has already swapped in a new Vpb. If this is the final reference - // then the file system is responsible for deleting the Vpb. - // - - } else if (FinalReference) { - - // - // Make sure to remove the last reference on the Vpb. - // - - OldVpb->ReferenceCount -= 1; - - IoReleaseVpbSpinLock( SavedIrql ); - CdUnlockVcb( IrpContext, Vcb ); - CdDeleteVcb( IrpContext, Vcb ); - VcbPresent = FALSE; - - // - // The current Vpb is no longer the Vpb for the device (the IO system - // has already allocated a new one). We leave our reference in the - // Vpb and will be responsible for deleting it at a later time. - // - - } else { - - IoReleaseVpbSpinLock( SavedIrql ); - CdUnlockVcb( IrpContext, Vcb ); - } - - // - // Let our caller know whether the Vcb is still present. - // - - return VcbPresent; -} - diff --git a/reactos/drivers/filesystems/cdfs_new/volinfo.c b/reactos/drivers/filesystems/cdfs_new/volinfo.c deleted file mode 100755 index e592f98123b..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/volinfo.c +++ /dev/null @@ -1,505 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - VolInfo.c - -Abstract: - - This module implements the volume information routines for Cdfs called by - the dispatch driver. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_VOLINFO) - -// -// Local support routines -// - -NTSTATUS -CdQueryFsVolumeInfo ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_FS_VOLUME_INFORMATION Buffer, - IN OUT PULONG Length - ); - -NTSTATUS -CdQueryFsSizeInfo ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_FS_SIZE_INFORMATION Buffer, - IN OUT PULONG Length - ); - -NTSTATUS -CdQueryFsDeviceInfo ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_FS_DEVICE_INFORMATION Buffer, - IN OUT PULONG Length - ); - -NTSTATUS -CdQueryFsAttributeInfo ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer, - IN OUT PULONG Length - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdCommonQueryVolInfo) -#pragma alloc_text(PAGE, CdQueryFsAttributeInfo) -#pragma alloc_text(PAGE, CdQueryFsDeviceInfo) -#pragma alloc_text(PAGE, CdQueryFsSizeInfo) -#pragma alloc_text(PAGE, CdQueryFsVolumeInfo) -#endif - - -NTSTATUS -CdCommonQueryVolInfo ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This is the common routine for querying volume information called by both - the fsd and fsp threads. - -Arguments: - - Irp - Supplies the Irp being processed - -Return Value: - - NTSTATUS - The return status for the operation - ---*/ - -{ - NTSTATUS Status = STATUS_INVALID_PARAMETER; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - ULONG Length; - - TYPE_OF_OPEN TypeOfOpen; - PFCB Fcb; - PCCB Ccb; - - PAGED_CODE(); - - // - // Reference our input parameters to make things easier - // - - Length = IrpSp->Parameters.QueryVolume.Length; - - // - // Decode the file object and fail if this an unopened file object. - // - - TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ); - - if (TypeOfOpen == UnopenedFileObject) { - - CdCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); - return STATUS_INVALID_PARAMETER; - } - - // - // Acquire the Vcb for this volume. - // - - CdAcquireVcbShared( IrpContext, Fcb->Vcb, FALSE ); - - // - // Use a try-finally to facilitate cleanup. - // - - try { - - // - // Verify the Vcb. - // - - CdVerifyVcb( IrpContext, Fcb->Vcb ); - - // - // Based on the information class we'll do different actions. Each - // of the procedures that we're calling fills up the output buffer - // if possible and returns true if it successfully filled the buffer - // and false if it couldn't wait for any I/O to complete. - // - - switch (IrpSp->Parameters.QueryVolume.FsInformationClass) { - - case FileFsSizeInformation: - - Status = CdQueryFsSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length ); - break; - - case FileFsVolumeInformation: - - Status = CdQueryFsVolumeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length ); - break; - - case FileFsDeviceInformation: - - Status = CdQueryFsDeviceInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length ); - break; - - case FileFsAttributeInformation: - - Status = CdQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length ); - break; - - /* ReactOS Change: GCC "enumeration value not handled in switch" */ - default: break; - } - - // - // Set the information field to the number of bytes actually filled in - // - - Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length; - - } finally { - - // - // Release the Vcb. - // - - CdReleaseVcb( IrpContext, Fcb->Vcb ); - } - - // - // Complete the request if we didn't raise. - // - - CdCompleteRequest( IrpContext, Irp, Status ); - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdQueryFsVolumeInfo ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_FS_VOLUME_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - -Routine Description: - - This routine implements the query volume info call - -Arguments: - - Vcb - Vcb for this volume. - - Buffer - Supplies a pointer to the output buffer where the information - is to be returned - - Length - Supplies the length of the buffer in byte. This variable - upon return recieves the remaining bytes free in the buffer - -Return Value: - - NTSTATUS - Returns the status for the query - ---*/ - -{ - ULONG BytesToCopy; - - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - // - // Fill in the data from the Vcb. - // - - Buffer->VolumeCreationTime = *((PLARGE_INTEGER) &Vcb->VolumeDasdFcb->CreationTime); - Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber; - - Buffer->SupportsObjects = FALSE; - - *Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel[0] ); - - // - // Check if the buffer we're given is long enough - // - - if (*Length >= (ULONG) Vcb->Vpb->VolumeLabelLength) { - - BytesToCopy = Vcb->Vpb->VolumeLabelLength; - - } else { - - BytesToCopy = *Length; - - Status = STATUS_BUFFER_OVERFLOW; - } - - // - // Copy over what we can of the volume label, and adjust *Length - // - - Buffer->VolumeLabelLength = BytesToCopy; - - if (BytesToCopy) { - - RtlCopyMemory( &Buffer->VolumeLabel[0], - &Vcb->Vpb->VolumeLabel[0], - BytesToCopy ); - } - - *Length -= BytesToCopy; - - // - // Set our status and return to our caller - // - - return Status; -} - - -// -// Local support routine -// - -NTSTATUS -CdQueryFsSizeInfo ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_FS_SIZE_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - -Routine Description: - - This routine implements the query volume size call. - -Arguments: - - Vcb - Vcb for this volume. - - Buffer - Supplies a pointer to the output buffer where the information - is to be returned - - Length - Supplies the length of the buffer in byte. This variable - upon return recieves the remaining bytes free in the buffer - -Return Value: - - NTSTATUS - Returns the status for the query - ---*/ - -{ - PAGED_CODE(); - - // - // Fill in the output buffer. - // - - Buffer->TotalAllocationUnits.QuadPart = LlSectorsFromBytes( Vcb->VolumeDasdFcb->AllocationSize.QuadPart ); - - Buffer->AvailableAllocationUnits.QuadPart = 0; - Buffer->SectorsPerAllocationUnit = 1; - Buffer->BytesPerSector = SECTOR_SIZE; - - // - // Adjust the length variable - // - - *Length -= sizeof( FILE_FS_SIZE_INFORMATION ); - - // - // And return success to our caller - // - - return STATUS_SUCCESS; -} - - -// -// Local support routine -// - -NTSTATUS -CdQueryFsDeviceInfo ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_FS_DEVICE_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - -Routine Description: - - This routine implements the query volume device call. - -Arguments: - - Vcb - Vcb for this volume. - - Buffer - Supplies a pointer to the output buffer where the information - is to be returned - - Length - Supplies the length of the buffer in byte. This variable - upon return recieves the remaining bytes free in the buffer - -Return Value: - - NTSTATUS - Returns the status for the query - ---*/ - -{ - PAGED_CODE(); - - // - // Update the output buffer. - // - - Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics; - Buffer->DeviceType = FILE_DEVICE_CD_ROM; - - // - // Adjust the length variable - // - - *Length -= sizeof( FILE_FS_DEVICE_INFORMATION ); - - // - // And return success to our caller - // - - return STATUS_SUCCESS; -} - - -// -// Local support routine -// - -NTSTATUS -CdQueryFsAttributeInfo ( - IN PIRP_CONTEXT IrpContext, - IN PVCB Vcb, - IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer, - IN OUT PULONG Length - ) - -/*++ - -Routine Description: - - This routine implements the query volume attribute call. - -Arguments: - - Vcb - Vcb for this volume. - - Buffer - Supplies a pointer to the output buffer where the information - is to be returned - - Length - Supplies the length of the buffer in byte. This variable - upon return recieves the remaining bytes free in the buffer - -Return Value: - - NTSTATUS - Returns the status for the query - ---*/ - -{ - ULONG BytesToCopy; - - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - // - // Fill out the fixed portion of the buffer. - // - - Buffer->FileSystemAttributes = FILE_CASE_SENSITIVE_SEARCH | - FILE_READ_ONLY_VOLUME; - - if (FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) { - - SetFlag( Buffer->FileSystemAttributes, FILE_UNICODE_ON_DISK ); - - Buffer->MaximumComponentNameLength = 110; - - } else { - - Buffer->MaximumComponentNameLength = 221; - } - - *Length -= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName ); - - // - // Make sure we can copy full unicode characters. - // - - ClearFlag( *Length, 1 ); - - // - // Determine how much of the file system name will fit. - // - - if (*Length >= 8) { - - BytesToCopy = 8; - - } else { - - BytesToCopy = *Length; - Status = STATUS_BUFFER_OVERFLOW; - } - - *Length -= BytesToCopy; - - // - // Do the file system name. - // - - Buffer->FileSystemNameLength = BytesToCopy; - - RtlCopyMemory( &Buffer->FileSystemName[0], L"CDFS", BytesToCopy ); - - // - // And return to our caller - // - - return Status; -} - diff --git a/reactos/drivers/filesystems/cdfs_new/wdk_wnet_to_ros.diff b/reactos/drivers/filesystems/cdfs_new/wdk_wnet_to_ros.diff deleted file mode 100644 index 49e7a3a7119..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/wdk_wnet_to_ros.diff +++ /dev/null @@ -1,1073 +0,0 @@ -Index: drivers/filesystems/cdfs_new/deviosup.c -=================================================================== ---- drivers/filesystems/cdfs_new/deviosup.c (revision 34615) -+++ drivers/filesystems/cdfs_new/deviosup.c (working copy) -@@ -165,6 +165,7 @@ - ); - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdMultiSyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, -@@ -172,6 +173,7 @@ - ); - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdMultiAsyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, -@@ -179,6 +181,7 @@ - ); - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdSingleSyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, -@@ -186,6 +189,7 @@ - ); - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdSingleAsyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, -@@ -2943,6 +2947,7 @@ - // - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdMultiSyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, -@@ -3029,6 +3034,7 @@ - // - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdMultiAsyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, -@@ -3066,7 +3072,8 @@ - - { - PCD_IO_CONTEXT IoContext = Context; -- PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); -+ /* ReactOS Change: GCC Unused Variable */ -+ //PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - AssertVerifyDeviceIrp( Irp ); - -@@ -3148,6 +3155,7 @@ - // - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdSingleSyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, -@@ -3207,6 +3215,7 @@ - // - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdSingleAsyncCompletionRoutine ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, -@@ -3267,7 +3276,7 @@ - // and finally, free the context record. - // - -- CdFreeIoContext( (PCD_IO_CONTEXT) Context ); -+ CdFreeIoContext( Context ); /* ReactOS Change: GCC "error: invalid lvalue in unary '&'" */ - return STATUS_SUCCESS; - - UNREFERENCED_PARAMETER( DeviceObject ); -Index: drivers/filesystems/cdfs_new/dirctrl.c -=================================================================== ---- drivers/filesystems/cdfs_new/dirctrl.c (revision 34615) -+++ drivers/filesystems/cdfs_new/dirctrl.c (working copy) -@@ -209,7 +209,7 @@ - - ULONG BaseLength; - -- PFILE_BOTH_DIR_INFORMATION DirInfo; -+ PFILE_BOTH_DIR_INFORMATION DirInfo = NULL; /* ReactOS Change: GCC Uninit var */ - PFILE_NAMES_INFORMATION NamesInfo; - PFILE_ID_FULL_DIR_INFORMATION IdFullDirInfo; - PFILE_ID_BOTH_DIR_INFORMATION IdBothDirInfo; -@@ -579,6 +579,9 @@ - NamesInfo->FileNameLength = FileNameBytes + SeparatorBytes + VersionStringBytes; - - break; -+ -+ /* ReactOS Change: GCC "enumeration value not handled in switch" */ -+ default: break; - } - - // -Index: drivers/filesystems/cdfs_new/create.c -=================================================================== ---- drivers/filesystems/cdfs_new/create.c (revision 34615) -+++ drivers/filesystems/cdfs_new/create.c (working copy) -@@ -2106,7 +2106,7 @@ - PFCB NextFcb; - PFCB ParentFcb = NULL; - -- NTSTATUS Status; -+ NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC uninitialized variable */ - - PAGED_CODE(); - -@@ -2757,8 +2757,8 @@ - OplockStatus = FsRtlCheckOplock( &Fcb->Oplock, - IrpContext->Irp, - IrpContext, -- CdOplockComplete, -- CdPrePostIrp ); -+ (PVOID)CdOplockComplete, /* ReactOS Change: GCC "assignment from incompatible pointer type" */ -+ (PVOID)CdPrePostIrp ); /* ReactOS Change: GCC "assignment from incompatible pointer type" */ - - if (OplockStatus == STATUS_PENDING) { - -@@ -2789,8 +2789,8 @@ - OplockStatus = FsRtlCheckOplock( &Fcb->Oplock, - IrpContext->Irp, - IrpContext, -- CdOplockComplete, -- CdPrePostIrp ); -+ (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */ -+ (PVOID)CdPrePostIrp );/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - - if (OplockStatus == STATUS_PENDING) { - -Index: drivers/filesystems/cdfs_new/devctrl.c -=================================================================== ---- drivers/filesystems/cdfs_new/devctrl.c (revision 34615) -+++ drivers/filesystems/cdfs_new/devctrl.c (working copy) -@@ -64,7 +64,7 @@ - PIO_STACK_LOCATION IrpSp; - PIO_STACK_LOCATION NextIrpSp; - -- PVOID TargetBuffer = NULL; -+// PVOID TargetBuffer = NULL; /* ReactOS Change: GCC unused variable */ - - PAGED_CODE(); - -Index: drivers/filesystems/cdfs_new/close.c -=================================================================== ---- drivers/filesystems/cdfs_new/close.c (revision 34615) -+++ drivers/filesystems/cdfs_new/close.c (working copy) -@@ -77,6 +77,7 @@ - ); - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdCloseWorker ( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context -@@ -136,9 +137,9 @@ - // - // Continue processing until there are no more closes to process. - // -+ /* ReactOS Change: "GCC suggest parentheses around assignment used as truth value" */ -+ while ((IrpContext = CdRemoveClose( Vcb ))) { - -- while (IrpContext = CdRemoveClose( Vcb )) { -- - // - // If we don't have an IrpContext then use the one on the stack. - // Initialize it for this request. -@@ -165,7 +166,7 @@ - // Free the IrpContextLite. - // - -- CdFreeIrpContextLite( (PIRP_CONTEXT_LITE) IrpContext ); -+ CdFreeIrpContextLite( IrpContext ); /* ReactOS Change: GCC "error: invalid lvalue in unary '&'" */ - - // - // Remember we have the IrpContext from the stack. -@@ -662,6 +663,7 @@ - } - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdCloseWorker ( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context -Index: drivers/filesystems/cdfs_new/dirsup.c -=================================================================== ---- drivers/filesystems/cdfs_new/dirsup.c (revision 34615) -+++ drivers/filesystems/cdfs_new/dirsup.c (working copy) -@@ -465,7 +465,7 @@ - // Save a pointer to the time stamps. - // - -- Dirent->CdTime = RawDirent->RecordTime; -+ Dirent->CdTime = (PCHAR)RawDirent->RecordTime; /* ReactOS change: GCC "pointer targets in assignment differ in signedness" */ - - // - // Copy the dirent flags. -@@ -501,7 +501,7 @@ - } - - Dirent->FileNameLen = RawDirent->FileIdLen; -- Dirent->FileName = RawDirent->FileId; -+ Dirent->FileName = (PCHAR)RawDirent->FileId; /* ReactOS change: GCC "pointer targets in assignment differ in signedness" */ - - // - // If there are any remaining bytes at the end of the dirent then -@@ -1457,7 +1457,7 @@ - --*/ - - { -- XA_EXTENT_TYPE ExtentType; -+ XA_EXTENT_TYPE ExtentType = 0; /* ReactOS Change: GCC Uninit var */ - PCOMPOUND_DIRENT CurrentCompoundDirent; - PDIRENT CurrentDirent; - -Index: drivers/filesystems/cdfs_new/read.c -=================================================================== ---- drivers/filesystems/cdfs_new/read.c (revision 34615) -+++ drivers/filesystems/cdfs_new/read.c (working copy) -@@ -79,7 +79,7 @@ - --*/ - - { -- NTSTATUS Status; -+ NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC Uninit var */ - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - TYPE_OF_OPEN TypeOfOpen; -@@ -225,8 +225,8 @@ - Status = FsRtlCheckOplock( &Fcb->Oplock, - Irp, - IrpContext, -- CdOplockComplete, -- CdPrePostIrp ); -+ (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */ -+ (PVOID)CdPrePostIrp );/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - - // - // If the result is not STATUS_SUCCESS then the Irp was completed -Index: drivers/filesystems/cdfs_new/volinfo.c -=================================================================== ---- drivers/filesystems/cdfs_new/volinfo.c (revision 34615) -+++ drivers/filesystems/cdfs_new/volinfo.c (working copy) -@@ -166,8 +166,11 @@ - - Status = CdQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length ); - break; -+ -+ /* ReactOS Change: GCC "enumeration value not handled in switch" */ -+ default: break; - } -- -+ - // - // Set the information field to the number of bytes actually filled in - // -Index: drivers/filesystems/cdfs_new/cdfs.rbuild -=================================================================== ---- drivers/filesystems/cdfs_new/cdfs.rbuild (revision 34615) -+++ drivers/filesystems/cdfs_new/cdfs.rbuild (working copy) -@@ -1,8 +1,8 @@ - - -- -+ - -- . -+ . - ntoskrnl - hal - allocsup.c -@@ -32,6 +32,5 @@ - volinfo.c - workque.c - cdfs.rc -- -fms-extensions - cdprocs.h - -Index: drivers/filesystems/cdfs_new/cddata.c -=================================================================== ---- drivers/filesystems/cdfs_new/cddata.c (revision 34615) -+++ drivers/filesystems/cdfs_new/cddata.c (working copy) -@@ -417,7 +417,6 @@ - return Status; - } - -- - #ifdef CD_SANITY - - VOID -@@ -481,7 +480,6 @@ - - #endif - -- - LONG - CdExceptionFilter ( - IN PIRP_CONTEXT IrpContext, -@@ -1006,6 +1004,7 @@ - - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastIoCheckIfPossible ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, -Index: drivers/filesystems/cdfs_new/allocsup.c -=================================================================== ---- drivers/filesystems/cdfs_new/allocsup.c (revision 34615) -+++ drivers/filesystems/cdfs_new/allocsup.c (working copy) -@@ -128,7 +128,7 @@ - { - BOOLEAN FirstPass = TRUE; - ULONG McbEntryOffset; -- PFCB ParentFcb; -+ PFCB ParentFcb = NULL; /* ReactOS Change: GCC uninitialized variable bug */ - BOOLEAN CleanupParent = FALSE; - - BOOLEAN UnlockFcb = FALSE; -Index: drivers/filesystems/cdfs_new/verfysup.c -=================================================================== ---- drivers/filesystems/cdfs_new/verfysup.c (revision 34615) -+++ drivers/filesystems/cdfs_new/verfysup.c (working copy) -@@ -431,7 +431,7 @@ - ULONG MediaChangeCount = 0; - BOOLEAN ForceVerify = FALSE; - BOOLEAN DevMarkedForVerify; -- KIRQL SavedIrql; -+ //KIRQL SavedIrql; /* ReactOS Change: GCC Unused variable */ - - PAGED_CODE(); - -@@ -581,6 +581,9 @@ - - CdRaiseStatus( IrpContext, STATUS_FILE_INVALID ); - break; -+ -+ /* ReactOS Change: GCC "enumeration value not handled in switch" */ -+ default: break; - } - } - -@@ -613,7 +616,7 @@ - --*/ - - { -- NTSTATUS Status = STATUS_SUCCESS; -+ //NTSTATUS Status = STATUS_SUCCESS; /* ReactOS Change: GCC Unused variable */ - PVCB Vcb = Fcb->Vcb; - PDEVICE_OBJECT RealDevice = Vcb->Vpb->RealDevice; - PIRP Irp; -Index: drivers/filesystems/cdfs_new/filobsup.c -=================================================================== ---- drivers/filesystems/cdfs_new/filobsup.c (revision 34615) -+++ drivers/filesystems/cdfs_new/filobsup.c (working copy) -@@ -105,7 +105,7 @@ - FileObject->FsContext = Fcb; - FileObject->FsContext2 = Ccb; - -- SetFlag( ((ULONG_PTR) FileObject->FsContext2), TypeOfOpen ); -+ SetFlag( (*(PULONG_PTR)&FileObject->FsContext2), TypeOfOpen ); /* ReactOS Change: GCC "invalid lvalue in assignment" */ - - // - // Set the Vpb field in the file object. -@@ -176,7 +176,7 @@ - *Fcb = FileObject->FsContext; - *Ccb = FileObject->FsContext2; - -- ClearFlag( (ULONG_PTR) *Ccb, TYPE_OF_OPEN_MASK ); -+ ClearFlag( (*(PULONG_PTR)Ccb), TYPE_OF_OPEN_MASK ); /* ReactOS Change: GCC "invalid lvalue in assignment" */ - } - - // -Index: drivers/filesystems/cdfs_new/pathsup.c -=================================================================== ---- drivers/filesystems/cdfs_new/pathsup.c (revision 34615) -+++ drivers/filesystems/cdfs_new/pathsup.c (working copy) -@@ -764,7 +764,7 @@ - - PathEntry->PathEntryLength = WordAlign( PathEntry->PathEntryLength ); - -- PathEntry->DirName = RawPathEntry->DirId; -+ PathEntry->DirName = (PCHAR)RawPathEntry->DirId; /* ReactOS Change: GCC "assignment makes pointer from integer without a cast" */ - - return TRUE; - } -Index: drivers/filesystems/cdfs_new/cdprocs.h -=================================================================== ---- drivers/filesystems/cdfs_new/cdprocs.h (revision 34615) -+++ drivers/filesystems/cdfs_new/cdprocs.h (working copy) -@@ -44,28 +44,30 @@ - // Here are the different pool tags. - // - --#define TAG_CCB 'ccdC' // Ccb --#define TAG_CDROM_TOC 'ctdC' // TOC --#define TAG_DIRENT_NAME 'nddC' // CdName in dirent --#define TAG_ENUM_EXPRESSION 'eedC' // Search expression for enumeration --#define TAG_FCB_DATA 'dfdC' // Data Fcb --#define TAG_FCB_INDEX 'ifdC' // Index Fcb --#define TAG_FCB_NONPAGED 'nfdC' // Nonpaged Fcb --#define TAG_FCB_TABLE 'tfdC' // Fcb Table entry --#define TAG_FILE_NAME 'nFdC' // Filename buffer --#define TAG_GEN_SHORT_NAME 'sgdC' // Generated short name --#define TAG_IO_BUFFER 'fbdC' // Temporary IO buffer --#define TAG_IO_CONTEXT 'oidC' // Io context for async reads --#define TAG_IRP_CONTEXT 'cidC' // Irp Context --#define TAG_IRP_CONTEXT_LITE 'lidC' // Irp Context lite --#define TAG_MCB_ARRAY 'amdC' // Mcb array --#define TAG_PATH_ENTRY_NAME 'nPdC' // CdName in path entry --#define TAG_PREFIX_ENTRY 'epdC' // Prefix Entry --#define TAG_PREFIX_NAME 'npdC' // Prefix Entry name --#define TAG_SPANNING_PATH_TABLE 'psdC' // Buffer for spanning path table --#define TAG_UPCASE_NAME 'nudC' // Buffer for upcased name --#define TAG_VOL_DESC 'dvdC' // Buffer for volume descriptor --#define TAG_VPB 'pvdC' // Vpb allocated in filesystem -+/* ReactOS Change: GCC doesn't understand this, use TAG macro */ -+#include -+#define TAG_CCB TAG('c','c','d','C') // Ccb -+#define TAG_CDROM_TOC TAG('c','t','d','C') // TOC -+#define TAG_DIRENT_NAME TAG('n','d','d','C') // CdName in dirent -+#define TAG_ENUM_EXPRESSION TAG('e','e','d','C') // Search expression for enumeration -+#define TAG_FCB_DATA TAG('d','f','d','C') // Data Fcb -+#define TAG_FCB_INDEX TAG('i','f','d','C') // Index Fcb -+#define TAG_FCB_NONPAGED TAG('n','f','d','C') // Nonpaged Fcb -+#define TAG_FCB_TABLE TAG('t','f','d','C') // Fcb Table entry -+#define TAG_FILE_NAME TAG('n','F','d','C') // Filename buffer -+#define TAG_GEN_SHORT_NAME TAG('s','g','d','C') // Generated short name -+#define TAG_IO_BUFFER TAG('f','b','d','C') // Temporary IO buffer -+#define TAG_IO_CONTEXT TAG('o','i','d','C') // Io context for async reads -+#define TAG_IRP_CONTEXT TAG('c','i','d','C') // Irp Context -+#define TAG_IRP_CONTEXT_LITE TAG('l','i','d','C') // Irp Context lite -+#define TAG_MCB_ARRAY TAG('a','m','d','C') // Mcb array -+#define TAG_PATH_ENTRY_NAME TAG('n','P','d','C') // CdName in path entry -+#define TAG_PREFIX_ENTRY TAG('e','p','d','C') // Prefix Entry -+#define TAG_PREFIX_NAME TAG('n','p','d','C') // Prefix Entry name -+#define TAG_SPANNING_PATH_TABLE TAG('p','s','d','C') // Buffer for spanning path table -+#define TAG_UPCASE_NAME TAG('n','u','d','C') // Buffer for upcased name -+#define TAG_VOL_DESC TAG('d','v','d','C') // Buffer for volume descriptor -+#define TAG_VPB TAG('p','v','d','C') // Vpb allocated in filesystem - - // - // Tag all of our allocations if tagging is turned on -@@ -902,33 +904,39 @@ - } - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdNoopAcquire ( - IN PVOID Fcb, - IN BOOLEAN Wait - ); - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdNoopRelease ( - IN PVOID Fcb - ); - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdAcquireForCache ( - IN PFCB Fcb, - IN BOOLEAN Wait - ); - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdReleaseFromCache ( - IN PFCB Fcb - ); - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdAcquireForCreateSection ( - IN PFILE_OBJECT FileObject - ); - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdReleaseForCreateSection ( - IN PFILE_OBJECT FileObject - ); -@@ -1184,8 +1192,8 @@ - // Verification support routines. Contained in verfysup.c - // - -- --INLINE -+/* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */ -+static inline - BOOLEAN - CdOperationIsDasdOpen( - IN PIRP_CONTEXT IrpContext -@@ -1272,12 +1280,14 @@ - ); - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdPrePostIrp ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdOplockComplete ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp -@@ -1293,7 +1303,9 @@ - // otherwise - // - --//#ifndef BooleanFlagOn -+/* ReactOS Change: GCC doesn't understand the comment style */ -+/* -+ //#ifndef BooleanFlagOn - //#define BooleanFlagOn(F,SF) ( \ - // (BOOLEAN)(((F) & (SF)) != 0) \ - //) -@@ -1310,6 +1322,7 @@ - // (Flags) &= ~(SingleFlag); \ - //} - //#endif -+*/ - - // - // CAST -@@ -1598,6 +1611,7 @@ - // - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastQueryBasicInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, -@@ -1607,6 +1621,7 @@ - ); - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastQueryStdInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, -@@ -1616,6 +1631,7 @@ - ); - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastLock ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, -@@ -1629,6 +1645,7 @@ - ); - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastUnlockSingle ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, -@@ -1640,6 +1657,7 @@ - ); - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastUnlockAll ( - IN PFILE_OBJECT FileObject, - PEPROCESS ProcessId, -@@ -1648,6 +1666,7 @@ - ); - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastUnlockAllByKey ( - IN PFILE_OBJECT FileObject, - PVOID ProcessId, -@@ -1657,6 +1676,7 @@ - ); - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastIoCheckIfPossible ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, -@@ -1669,6 +1689,7 @@ - ); - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastQueryNetworkInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, -@@ -1862,17 +1883,26 @@ - // - // #define try_return(S) { S; goto try_exit; } - // -+/* ReactOS Change: Remove SEH */ -+#define try -+#define leave goto exitLabel; -+#define finally if (0) goto exitLabel; exitLabel: -+#define except(x) while (0) -+#define GetExceptionCode() 0 -+#define AbnormalTermination() 0 - --#define try_return(S) { S; goto try_exit; } --#define try_leave(S) { S; leave; } -+#define try_return(S) { goto try_exit; } -+#define try_leave(S) { leave; } - -+ - // - // Encapsulate safe pool freeing - // -+/* ReactOS Change: GCC "passing argument 1 of CdFreePool from incompatible pointer type" */ -+#define CdFreePool(x) _CdFreePool((PVOID*)(x)) - --INLINE --VOID --CdFreePool( -+/* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */ -+static inline void _CdFreePool( - IN PVOID *Pool - ) - { -Index: drivers/filesystems/cdfs_new/resrcsup.c -=================================================================== ---- drivers/filesystems/cdfs_new/resrcsup.c (revision 34615) -+++ drivers/filesystems/cdfs_new/resrcsup.c (working copy) -@@ -123,6 +123,7 @@ - - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdAcquireForCache ( - IN PFCB Fcb, - IN BOOLEAN Wait -@@ -159,6 +160,7 @@ - - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdReleaseFromCache ( - IN PFCB Fcb - ) -@@ -193,6 +195,7 @@ - - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdNoopAcquire ( - IN PVOID Fcb, - IN BOOLEAN Wait -@@ -224,6 +227,7 @@ - - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdNoopRelease ( - IN PVOID Fcb - ) -@@ -251,6 +255,7 @@ - - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdAcquireForCreateSection ( - IN PFILE_OBJECT FileObject - ) -@@ -298,6 +303,7 @@ - - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdReleaseForCreateSection ( - IN PFILE_OBJECT FileObject - ) -Index: drivers/filesystems/cdfs_new/namesup.c -=================================================================== ---- drivers/filesystems/cdfs_new/namesup.c (revision 34615) -+++ drivers/filesystems/cdfs_new/namesup.c (working copy) -@@ -206,7 +206,7 @@ - - { - NTSTATUS Status; -- PVOID NewBuffer; -+ //PVOID NewBuffer; /* ReactOS Change: GCC Uninitialized variable */ - - PAGED_CODE(); - -Index: drivers/filesystems/cdfs_new/cdinit.c -=================================================================== ---- drivers/filesystems/cdfs_new/cdinit.c (revision 34615) -+++ drivers/filesystems/cdfs_new/cdinit.c (working copy) -@@ -22,12 +22,14 @@ - #define BugCheckFileId (CDFS_BUG_CHECK_CDINIT) - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ); - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdUnload( - IN PDRIVER_OBJECT DriverObject - ); -@@ -39,6 +41,7 @@ - ); - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdShutdown ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp -@@ -57,6 +60,7 @@ - // - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath -@@ -169,6 +173,7 @@ - } - - NTSTATUS -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdShutdown ( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp -@@ -200,6 +205,7 @@ - - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdUnload( - IN PDRIVER_OBJECT DriverObject - ) -@@ -310,10 +316,10 @@ - // Initialize the cache manager callback routines - // - -- CdData.CacheManagerCallbacks.AcquireForLazyWrite = &CdAcquireForCache; -- CdData.CacheManagerCallbacks.ReleaseFromLazyWrite = &CdReleaseFromCache; -- CdData.CacheManagerCallbacks.AcquireForReadAhead = &CdAcquireForCache; -- CdData.CacheManagerCallbacks.ReleaseFromReadAhead = &CdReleaseFromCache; -+ CdData.CacheManagerCallbacks.AcquireForLazyWrite = (PVOID)&CdAcquireForCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */ -+ CdData.CacheManagerCallbacks.ReleaseFromLazyWrite = (PVOID)&CdReleaseFromCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */ -+ CdData.CacheManagerCallbacks.AcquireForReadAhead = (PVOID)&CdAcquireForCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */ -+ CdData.CacheManagerCallbacks.ReleaseFromReadAhead = (PVOID)&CdReleaseFromCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - - CdData.CacheManagerVolumeCallbacks.AcquireForLazyWrite = &CdNoopAcquire; - CdData.CacheManagerVolumeCallbacks.ReleaseFromLazyWrite = &CdNoopRelease; -Index: drivers/filesystems/cdfs_new/cdstruc.h -=================================================================== ---- drivers/filesystems/cdfs_new/cdstruc.h (revision 34615) -+++ drivers/filesystems/cdfs_new/cdstruc.h (working copy) -@@ -504,8 +504,8 @@ - // - - ULONG VcbCleanup; -- ULONG VcbReference; -- ULONG VcbUserReference; -+ LONG VcbReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */ -+ LONG VcbUserReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */ - - // - // Fcb for the Volume Dasd file, root directory and the Path Table. -@@ -655,7 +655,7 @@ - // executed later. - // - -- ULONG PostedRequestCount; -+ LONG PostedRequestCount; /* ReactOS Change: GCC "pointer targets in passing argument 1 of 'InterlockedDecrement' differ in signedness" */ - - // - // The following field indicates the number of IRP's waiting -@@ -878,7 +878,7 @@ - // - - ULONG FcbCleanup; -- ULONG FcbReference; -+ LONG FcbReference; /* ReactOS Change: GCC 'pointer targets in passing argument 1 of 'InterlockedXxx' differ in signedness */ - ULONG FcbUserReference; - - // -Index: drivers/filesystems/cdfs_new/lockctrl.c -=================================================================== ---- drivers/filesystems/cdfs_new/lockctrl.c (revision 34615) -+++ drivers/filesystems/cdfs_new/lockctrl.c (working copy) -@@ -89,7 +89,7 @@ - Status = FsRtlCheckOplock( &Fcb->Oplock, - Irp, - IrpContext, -- CdOplockComplete, -+ (PVOID)CdOplockComplete,/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - NULL ); - - // -@@ -138,6 +138,7 @@ - - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastLock ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, -@@ -246,8 +247,8 @@ - // - // Now call the FsRtl routine to perform the lock request. - // -- -- if (Results = FsRtlFastLock( Fcb->FileLock, -+ /* ReactOS Change: GCC "suggest parentheses around assignment used as truth value" */ -+ if ((Results = FsRtlFastLock( Fcb->FileLock, - FileObject, - FileOffset, - Length, -@@ -257,7 +258,7 @@ - ExclusiveLock, - IoStatus, - NULL, -- FALSE )) { -+ FALSE ))) { - - // - // Set the flag indicating if Fast I/O is questionable. We -@@ -284,6 +285,7 @@ - - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastUnlockSingle ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, -@@ -424,6 +426,7 @@ - - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastUnlockAll ( - IN PFILE_OBJECT FileObject, - PEPROCESS ProcessId, -@@ -546,6 +549,7 @@ - - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastUnlockAllByKey ( - IN PFILE_OBJECT FileObject, - PVOID ProcessId, -Index: drivers/filesystems/cdfs_new/cleanup.c -=================================================================== ---- drivers/filesystems/cdfs_new/cleanup.c (revision 34615) -+++ drivers/filesystems/cdfs_new/cleanup.c (working copy) -@@ -159,7 +159,7 @@ - // Use a try-finally to facilitate cleanup. - // - -- try { -+ //try { /* ReactOS Change: Manual removal of SEH since macros to hack around it don't allow multiple SEH usage within one function */ - - // - // Case on the type of open that we are trying to cleanup. -@@ -279,7 +279,7 @@ - - IoRemoveShareAccess( FileObject, &Fcb->ShareAccess ); - -- } finally { -+ //} finally { /* ReactOS Change: Manual removal of SEH since macros to hack around it don't allow multiple SEH usage within one function */ - - CdReleaseFcb( IrpContext, Fcb ); - -@@ -287,7 +287,7 @@ - - FsRtlNotifyVolumeEvent( FileObject, FSRTL_VOLUME_UNLOCK ); - } -- } -+ //} /* ReactOS Change: Manual removal of SEH since macros to hack around it don't allow multiple SEH usage within one function */ - - // - // If appropriate, try to spark teardown by purging the volume. Should -Index: drivers/filesystems/cdfs_new/strucsup.c -=================================================================== ---- drivers/filesystems/cdfs_new/strucsup.c (revision 34615) -+++ drivers/filesystems/cdfs_new/strucsup.c (working copy) -@@ -438,7 +438,7 @@ - --*/ - - { -- ULONG Shift; -+ //ULONG Shift; /* ReactOS Change: GCC Unused variable */ - ULONG StartingBlock; - ULONG ByteCount; - -Index: drivers/filesystems/cdfs_new/fileinfo.c -=================================================================== ---- drivers/filesystems/cdfs_new/fileinfo.c (revision 34615) -+++ drivers/filesystems/cdfs_new/fileinfo.c (working copy) -@@ -460,6 +460,7 @@ - - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastQueryBasicInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, -@@ -577,6 +578,7 @@ - - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastQueryStdInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, -@@ -704,6 +706,7 @@ - - - BOOLEAN -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdFastQueryNetworkInfo ( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, -Index: drivers/filesystems/cdfs_new/nodetype.h -=================================================================== ---- drivers/filesystems/cdfs_new/nodetype.h (revision 34615) -+++ drivers/filesystems/cdfs_new/nodetype.h (working copy) -@@ -97,6 +97,8 @@ - #define CDFS_BUG_CHECK_VOLINFO (0x001b0000) - #define CDFS_BUG_CHECK_WORKQUE (0x001c0000) - -+/* ReactOS Change: Need to add to reactos.mc */ -+#define CDFS_FILE_SYSTEM ((ULONG)0x00000026L) - #define CdBugCheck(A,B,C) { KeBugCheckEx(CDFS_FILE_SYSTEM, BugCheckFileId | __LINE__, A, B, C ); } - - #endif // _NODETYPE_ -Index: drivers/filesystems/cdfs_new/fsctrl.c -=================================================================== ---- drivers/filesystems/cdfs_new/fsctrl.c (revision 34615) -+++ drivers/filesystems/cdfs_new/fsctrl.c (working copy) -@@ -82,7 +82,8 @@ - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); -- -+ -+NTSTATUS /* ReactOS Change: Function did not have a type??? */ - CdIsVolumeDirty ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp -@@ -918,7 +919,7 @@ - - if (CdIsRemount( IrpContext, Vcb, &OldVcb )) { - -- KIRQL SavedIrql; -+ //KIRQL SavedIrql; /* ReactOS Change: GCC Unused variable */ - - ASSERT( NULL != OldVcb->SwapVpb ); - -@@ -1374,7 +1375,7 @@ - // Compute the length of the volume name - // - -- AnsiLabel.Buffer = CdRvdVolId( RawIsoVd, Vcb->VcbState ); -+ AnsiLabel.Buffer = (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ); /* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - AnsiLabel.MaximumLength = AnsiLabel.Length = VOLUME_ID_LENGTH; - - UnicodeLabel.MaximumLength = VOLUME_ID_LENGTH * sizeof( WCHAR ); -@@ -1401,7 +1402,7 @@ - } else { - - CdConvertBigToLittleEndian( IrpContext, -- CdRvdVolId( RawIsoVd, Vcb->VcbState ), -+ (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ),/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - VOLUME_ID_LENGTH, - (PCHAR) VolumeLabel ); - -@@ -2005,7 +2006,7 @@ - // - // Local support routine - // -- -+NTSTATUS /* ReactOS Change: Function did not have a type??? */ - CdIsVolumeDirty ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp -@@ -2294,9 +2295,9 @@ - - Status = ObReferenceObjectByHandle( Handle, - 0, -- *IoFileObjectType, -+ IoFileObjectType, /* ReactOS Change: GCC/LD Incompatibily with exported kernel data */ - KernelMode, -- &FileToMarkBad, -+ (PVOID*)&FileToMarkBad, /* ReactOS Change: GCC "passing argument 5 of 'ObReferenceObjectByHandle' from incompatible pointer type" */ - NULL ); - - if (!NT_SUCCESS(Status)) { -@@ -2642,8 +2643,8 @@ - // The track address is BigEndian, we need to flip the bytes. - // - -- Source = (PUCHAR) &CdromToc->TrackData[0].Address[3]; -- Dest = (PUCHAR) &BaseSector; -+ Source = (PCHAR) &CdromToc->TrackData[0].Address[3];/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ -+ Dest = (PCHAR) &BaseSector; /* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - - do { - -@@ -3118,7 +3119,7 @@ - if (NT_SUCCESS( RtlOemToUnicodeN( &Vcb->Vpb->VolumeLabel[0], - MAXIMUM_VOLUME_LABEL_LENGTH, - &Length, -- CdRvdVolId( RawIsoVd, Vcb->VcbState ), -+ (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ),/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - VOLUME_ID_LENGTH ))) { - - Vcb->Vpb->VolumeLabelLength = (USHORT) Length; -@@ -3131,7 +3132,7 @@ - } else { - - CdConvertBigToLittleEndian( IrpContext, -- CdRvdVolId( RawIsoVd, Vcb->VcbState ), -+ (PCHAR)CdRvdVolId( RawIsoVd, Vcb->VcbState ),/* ReactOS Change: GCC "pointer targets in assignment differ in signedness" */ - VOLUME_ID_LENGTH, - (PCHAR) Vcb->Vpb->VolumeLabel ); - -Index: drivers/filesystems/cdfs_new/workque.c -=================================================================== ---- drivers/filesystems/cdfs_new/workque.c (revision 34615) -+++ drivers/filesystems/cdfs_new/workque.c (working copy) -@@ -97,6 +97,7 @@ - - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdPrePostIrp ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp -@@ -209,6 +210,7 @@ - - - VOID -+NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ - CdOplockComplete ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp -@@ -386,7 +388,7 @@ - // - - ExInitializeWorkItem( &IrpContext->WorkQueueItem, -- CdFspDispatch, -+ (PVOID)CdFspDispatch,/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - IrpContext ); - - ExQueueWorkItem( &IrpContext->WorkQueueItem, CriticalWorkQueue ); diff --git a/reactos/drivers/filesystems/cdfs_new/workque.c b/reactos/drivers/filesystems/cdfs_new/workque.c deleted file mode 100755 index 8abc28d8bd1..00000000000 --- a/reactos/drivers/filesystems/cdfs_new/workque.c +++ /dev/null @@ -1,400 +0,0 @@ -/*++ - -Copyright (c) 1989-2000 Microsoft Corporation - -Module Name: - - WorkQue.c - -Abstract: - - This module implements the Work queue routines for the Cdfs File - system. - - ---*/ - -#include "CdProcs.h" - -// -// The Bug check file id for this module -// - -#define BugCheckFileId (CDFS_BUG_CHECK_WORKQUE) - -// -// The following constant is the maximum number of ExWorkerThreads that we -// will allow to be servicing a particular target device at any one time. -// - -#define FSP_PER_DEVICE_THRESHOLD (2) - -// -// Local support routines -// - -VOID -CdAddToWorkque ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ); - -#ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, CdFsdPostRequest) -#pragma alloc_text(PAGE, CdOplockComplete) -#pragma alloc_text(PAGE, CdPrePostIrp) -#endif - - -NTSTATUS -CdFsdPostRequest ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine enqueues the request packet specified by IrpContext to the - work queue associated with the FileSystemDeviceObject. This is a FSD - routine. - -Arguments: - - IrpContext - Pointer to the IrpContext to be queued to the Fsp. - - Irp - I/O Request Packet. - -Return Value: - - STATUS_PENDING - ---*/ - -{ - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_IRP( Irp ); - - // - // Posting is a three step operation. First lock down any buffers - // in the Irp. Next cleanup the IrpContext for the post and finally - // add this to a workque. - // - - CdPrePostIrp( IrpContext, Irp ); - - CdAddToWorkque( IrpContext, Irp ); - - // - // And return to our caller - // - - return STATUS_PENDING; -} - - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdPrePostIrp ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine performs any neccessary work before STATUS_PENDING is - returned with the Fsd thread. This routine is called within the - filesystem and by the oplock package. - -Arguments: - - Context - Pointer to the IrpContext to be queued to the Fsp - - Irp - I/O Request Packet. - -Return Value: - - None. - ---*/ - -{ - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - BOOLEAN RemovedFcb; - - PAGED_CODE(); - - ASSERT_IRP_CONTEXT( IrpContext ); - ASSERT_IRP( Irp ); - - // - // Case on the type of the operation. - // - - switch (IrpContext->MajorFunction) { - - case IRP_MJ_CREATE : - - // - // If called from the oplock package then there is an - // Fcb to possibly teardown. We will call the teardown - // routine and release the Fcb if still present. The cleanup - // code in create will know not to release this Fcb because - // we will clear the pointer. - // - - if ((IrpContext->TeardownFcb != NULL) && - *(IrpContext->TeardownFcb) != NULL) { - - CdTeardownStructures( IrpContext, *(IrpContext->TeardownFcb), &RemovedFcb ); - - if (!RemovedFcb) { - - CdReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) ); - } - - *(IrpContext->TeardownFcb) = NULL; - IrpContext->TeardownFcb = NULL; - } - - break; - - // - // We need to lock the user's buffer, unless this is an MDL-read, - // in which case there is no user buffer. - // - - case IRP_MJ_READ : - - if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) { - - CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length ); - } - - break; - - // - // We also need to check whether this is a query file operation. - // - - case IRP_MJ_DIRECTORY_CONTROL : - - if (IrpContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) { - - CdLockUserBuffer( IrpContext, IrpSp->Parameters.QueryDirectory.Length ); - } - - break; - } - - // - // Cleanup the IrpContext for the post. - // - - SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); - CdCleanupIrpContext( IrpContext, TRUE ); - - // - // Mark the Irp to show that we've already returned pending to the user. - // - - IoMarkIrpPending( Irp ); - - return; -} - - -VOID -NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ -CdOplockComplete ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine is called by the oplock package when an oplock break has - completed, allowing an Irp to resume execution. If the status in - the Irp is STATUS_SUCCESS, then we queue the Irp to the Fsp queue. - Otherwise we complete the Irp with the status in the Irp. - - If we are completing due to an error then check if there is any - cleanup to do. - -Arguments: - - Irp - I/O Request Packet. - -Return Value: - - None. - ---*/ - -{ - BOOLEAN RemovedFcb; - - PAGED_CODE(); - - // - // Check on the return value in the Irp. If success then we - // are to post this request. - // - - if (Irp->IoStatus.Status == STATUS_SUCCESS) { - - // - // Check if there is any cleanup work to do. - // - - switch (IrpContext->MajorFunction) { - - case IRP_MJ_CREATE : - - // - // If called from the oplock package then there is an - // Fcb to possibly teardown. We will call the teardown - // routine and release the Fcb if still present. The cleanup - // code in create will know not to release this Fcb because - // we will clear the pointer. - // - - if (IrpContext->TeardownFcb != NULL) { - - CdTeardownStructures( IrpContext, *(IrpContext->TeardownFcb), &RemovedFcb ); - - if (!RemovedFcb) { - - CdReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) ); - } - - *(IrpContext->TeardownFcb) = NULL; - IrpContext->TeardownFcb = NULL; - } - - break; - } - - // - // Insert the Irp context in the workqueue. - // - - CdAddToWorkque( IrpContext, Irp ); - - // - // Otherwise complete the request. - // - - } else { - - CdCompleteRequest( IrpContext, Irp, Irp->IoStatus.Status ); - } - - return; -} - - -// -// Local support routine -// - -VOID -CdAddToWorkque ( - IN PIRP_CONTEXT IrpContext, - IN PIRP Irp - ) - -/*++ - -Routine Description: - - This routine is called to acually store the posted Irp to the Fsp - workque. - -Arguments: - - IrpContext - Pointer to the IrpContext to be queued to the Fsp - - Irp - I/O Request Packet. - -Return Value: - - None. - ---*/ - -{ - PVOLUME_DEVICE_OBJECT Vdo; - KIRQL SavedIrql; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - // - // Check if this request has an associated file object, and thus volume - // device object. - // - - if (IrpSp->FileObject != NULL) { - - - Vdo = CONTAINING_RECORD( IrpSp->DeviceObject, - VOLUME_DEVICE_OBJECT, - DeviceObject ); - - // - // Check to see if this request should be sent to the overflow - // queue. If not, then send it off to an exworker thread. - // - - KeAcquireSpinLock( &Vdo->OverflowQueueSpinLock, &SavedIrql ); - - if (Vdo->PostedRequestCount > FSP_PER_DEVICE_THRESHOLD) { - - // - // We cannot currently respond to this IRP so we'll just enqueue it - // to the overflow queue on the volume. - // - - InsertTailList( &Vdo->OverflowQueue, - &IrpContext->WorkQueueItem.List ); - - Vdo->OverflowQueueCount += 1; - - KeReleaseSpinLock( &Vdo->OverflowQueueSpinLock, SavedIrql ); - - return; - - } else { - - // - // We are going to send this Irp to an ex worker thread so up - // the count. - // - - Vdo->PostedRequestCount += 1; - - KeReleaseSpinLock( &Vdo->OverflowQueueSpinLock, SavedIrql ); - } - } - - // - // Send it off..... - // - - ExInitializeWorkItem( &IrpContext->WorkQueueItem, - (PVOID)CdFspDispatch,/* ReactOS Change: GCC "assignment from incompatible pointer type" */ - IrpContext ); - - ExQueueWorkItem( &IrpContext->WorkQueueItem, CriticalWorkQueue ); - - return; -} - - -