⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strucsup.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:

        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_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 );
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -