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

📄 dirctrl.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 4 页
字号:
                //  Finish up by filling in the FileId
                //

                switch ( FileInformationClass ) {

                case FileIdBothDirectoryInformation:

                    IdBothDirInfo = (PFILE_ID_BOTH_DIR_INFORMATION)&Buffer[NextEntry];
                    IdBothDirInfo->FileId.QuadPart = FatGenerateFileIdFromDirentAndOffset( Dcb, Dirent, NextVbo );
                    break;

                case FileIdFullDirectoryInformation:

                    IdFullDirInfo = (PFILE_ID_FULL_DIR_INFORMATION)&Buffer[NextEntry];
                    IdFullDirInfo->FileId.QuadPart = FatGenerateFileIdFromDirentAndOffset( Dcb, Dirent, NextVbo );
                    break;

                default:
                    break;
                }
            
            }  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.
                  //
                  
                  Irp->IoStatus.Information = 0;
                  UpdateCcb = FALSE;
                  try_return( Status = GetExceptionCode());
            }

            //
            //  Set ourselves up for the next iteration
            //

            LastEntry = NextEntry;
            NextEntry += (ULONG)QuadAlign(BaseLength + BytesConverted);

            CurrentVbo = NextVbo + sizeof( DIRENT );
        }

    try_exit: NOTHING;
    } finally {

        DebugUnwind( FatQueryDirectory );

        FatReleaseFcb( IrpContext, Dcb );

        //
        //  Unpin data in cache if still held.
        //

        FatUnpinBcb( IrpContext, Bcb );

        //
        //  Free any dynamically allocated string buffer
        //

        FatFreeStringBuffer( &LongFileName);

        //
        //  Perform any cleanup.  If this is the first query, then store
        //  the filename in the Ccb if successful.  Also update the
        //  VBO index for the next search.  This is done by transferring
        //  from shared access to exclusive access and copying the
        //  data from the local copies.
        //

        if (!AbnormalTermination()) {

            if (UpdateCcb) {

                //
                //  Store the most recent VBO to use as a starting point for
                //  the next search.
                //

                Ccb->OffsetToStartSearchFrom = CurrentVbo;
            }

            FatCompleteRequest( IrpContext, Irp, Status );
        }

        DebugTrace(-1, Dbg, "FatQueryDirectory -> %08lx\n", Status);

    }

    return Status;
}


//
//  Local Support Routine
//

VOID
FatGetDirTimes(
    PIRP_CONTEXT IrpContext,
    PDIRENT Dirent,
    PFILE_DIRECTORY_INFORMATION DirInfo
    )

/*++

Routine Description:

    This routine pulls the date/time information from a dirent and fills
    in the DirInfo structure.

Arguments:

    Dirent - Supplies the dirent
    DirInfo - Supplies the target structure

Return Value:

    VOID

--*/


{
    //
    //  Start with the Last Write Time.
    //

    DirInfo->LastWriteTime =
        FatFatTimeToNtTime( IrpContext,
                            Dirent->LastWriteTime,
                            0 );

    //
    //  These fields are only non-zero when in Chicago mode.
    //

    if (FatData.ChicagoMode) {

        //
        //  Do a quick check here for Creation and LastAccess
        //  times that are the same as the LastWriteTime.
        //

        if (*((UNALIGNED LONG *)&Dirent->CreationTime) ==
            *((UNALIGNED LONG *)&Dirent->LastWriteTime)) {

            DirInfo->CreationTime.QuadPart =

                DirInfo->LastWriteTime.QuadPart +
                Dirent->CreationMSec * 10 * 1000 * 10;

        } else {

            //
            //  Only do the really hard work if this field is non-zero.
            //

            if (((PUSHORT)Dirent)[8] != 0) {

                DirInfo->CreationTime =
                    FatFatTimeToNtTime( IrpContext,
                                        Dirent->CreationTime,
                                        Dirent->CreationMSec );

            } else {

                ExLocalTimeToSystemTime( &FatJanOne1980,
                                         &DirInfo->CreationTime );
            }
        }

        //
        //  Do a quick check for LastAccessDate.
        //

        if (*((PUSHORT)&Dirent->LastAccessDate) ==
            *((PUSHORT)&Dirent->LastWriteTime.Date)) {

            PFAT_TIME WriteTime;

            WriteTime = &Dirent->LastWriteTime.Time;

            DirInfo->LastAccessTime.QuadPart =
                DirInfo->LastWriteTime.QuadPart -
                UInt32x32To64(((WriteTime->DoubleSeconds * 2) +
                               (WriteTime->Minute * 60) +
                               (WriteTime->Hour * 60 * 60)),
                              1000 * 1000 * 10);

        } else {

            //
            //  Only do the really hard work if this field is non-zero.
            //

            if (((PUSHORT)Dirent)[9] != 0) {

                DirInfo->LastAccessTime =
                    FatFatDateToNtTime( IrpContext,
                                        Dirent->LastAccessDate );

            } else {

                ExLocalTimeToSystemTime( &FatJanOne1980,
                                         &DirInfo->LastAccessTime );
            }
        }
    }
}


//
//  Local Support Routine
//

NTSTATUS
FatNotifyChangeDirectory (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine performs the notify change directory 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;
    PVCB Vcb;
    PDCB Dcb;
    PCCB Ccb;
    ULONG CompletionFilter;
    BOOLEAN WatchTree;

    BOOLEAN CompleteRequest;

    //
    //  Get the current Stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "FatNotifyChangeDirectory...\n", 0);
    DebugTrace( 0, Dbg, " Wait               = %08lx\n", FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));
    DebugTrace( 0, Dbg, " Irp                = %08lx\n", Irp);
    DebugTrace( 0, Dbg, " ->CompletionFilter = %08lx\n", IrpSp->Parameters.NotifyDirectory.CompletionFilter);

    //
    //  Always set the wait flag in the Irp context for the original request.
    //

    SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );

    //
    //  Assume we don't complete request.
    //

    CompleteRequest = FALSE;

    //
    //  Check on the type of open.  We return invalid parameter for all
    //  but UserDirectoryOpens.
    //

    if (FatDecodeFileObject( IrpSp->FileObject,
                             &Vcb,
                             &Dcb,
                             &Ccb ) != UserDirectoryOpen) {

        FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
        DebugTrace(-1, Dbg, "FatQueryDirectory -> STATUS_INVALID_PARAMETER\n", 0);

        return STATUS_INVALID_PARAMETER;

    }

    //
    //  Reference our input parameter to make things easier
    //

    CompletionFilter = IrpSp->Parameters.NotifyDirectory.CompletionFilter;
    WatchTree = BooleanFlagOn( IrpSp->Flags, SL_WATCH_TREE );

    //
    //  Try to acquire exclusive access to the Dcb and enqueue the Irp to the
    //  Fsp if we didn't get access
    //

    if (!FatAcquireExclusiveFcb( IrpContext, Dcb )) {

        DebugTrace(0, Dbg, "FatNotifyChangeDirectory -> Cannot Acquire Fcb\n", 0);

        Status = FatFsdPostRequest( IrpContext, Irp );

        DebugTrace(-1, Dbg, "FatNotifyChangeDirectory -> %08lx\n", Status);
        return Status;
    }

    try {

        //
        //  Make sure the Fcb is still good
        //

        FatVerifyFcb( IrpContext, Dcb );

        //
        //  We need the full name.
        //

        FatSetFullFileNameInFcb( IrpContext, Dcb );

        //
        //  If the file is marked as DELETE_PENDING then complete this
        //  request immediately.
        //

        if (FlagOn( Dcb->FcbState, FCB_STATE_DELETE_ON_CLOSE )) {

            FatRaiseStatus( IrpContext, STATUS_DELETE_PENDING );
        }

        //
        //  Call the Fsrtl package to process the request.
        //

        FsRtlNotifyFullChangeDirectory( Vcb->NotifySync,
                                        &Vcb->DirNotifyList,
                                        Ccb,
                                        (PSTRING)&Dcb->FullFileName,
                                        WatchTree,
                                        FALSE,
                                        CompletionFilter,
                                        Irp,
                                        NULL,
                                        NULL );

        Status = STATUS_PENDING;

        CompleteRequest = TRUE;

    } finally {

        DebugUnwind( FatNotifyChangeDirectory );

        FatReleaseFcb( IrpContext, Dcb );

        //
        //  If the dir notify package is holding the Irp, we discard the
        //  the IrpContext.
        //

        if (CompleteRequest) {

            FatCompleteRequest( IrpContext, FatNull, 0 );
        }

        DebugTrace(-1, Dbg, "FatNotifyChangeDirectory -> %08lx\n", Status);
    }

    return Status;
}

⌨️ 快捷键说明

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