Exemplo n.º 1
0
IO_STATUS_BLOCK
NTAPI
FatiOpenExistingDcb(IN PFAT_IRP_CONTEXT IrpContext,
                    IN PFILE_OBJECT FileObject,
                    IN PVCB Vcb,
                    IN PFCB Dcb,
                    IN PACCESS_MASK DesiredAccess,
                    IN USHORT ShareAccess,
                    IN ULONG CreateDisposition,
                    IN BOOLEAN NoEaKnowledge,
                    IN BOOLEAN DeleteOnClose)
{
    IO_STATUS_BLOCK Iosb = {{0}};
    PCCB Ccb;

    /* Exclusively lock this FCB */
    FatAcquireExclusiveFcb(IrpContext, Dcb);

    /* Check if it's a delete-on-close of a root DCB */
    if (FatNodeType(Dcb) == FAT_NTC_ROOT_DCB && DeleteOnClose)
    {
        Iosb.Status = STATUS_CANNOT_DELETE;

        /* Release the lock and return */
        FatReleaseFcb(IrpContext, Dcb);
        return Iosb;
    }

    /*if (NoEaKnowledge && NodeType(Dcb) != FAT_NTC_ROOT_DCB &&
        !FatIsFat32(Vcb))
    {
        UNIMPLEMENTED;
    }*/

    /* Check the create disposition and desired access */
    if ((CreateDisposition != FILE_OPEN) &&
        (CreateDisposition != FILE_OPEN_IF))
    {
        Iosb.Status = STATUS_OBJECT_NAME_COLLISION;

        /* Release the lock and return */
        FatReleaseFcb(IrpContext, Dcb);
        return Iosb;
    }

#if 0
    if (!FatCheckFileAccess(IrpContext,
                            Dcb->DirentFatFlags,
                            DesiredAccess))
    {
        Iosb.Status = STATUS_ACCESS_DENIED;
        try_return( Iosb );
    }
#endif

    /* If it's already opened - check share access */
    if (Dcb->OpenCount > 0)
    {
        Iosb.Status = IoCheckShareAccess(*DesiredAccess,
                                         ShareAccess,
                                         FileObject,
                                         &Dcb->ShareAccess,
                                         TRUE);

        if (!NT_SUCCESS(Iosb.Status))
        {
            /* Release the lock and return */
            FatReleaseFcb(IrpContext, Dcb);
            return Iosb;
        }
    }
    else
    {
        IoSetShareAccess(*DesiredAccess,
                         ShareAccess,
                         FileObject,
                         &Dcb->ShareAccess);
    }

    /* Set the file object */
    Ccb = FatCreateCcb();
    FatSetFileObject(FileObject,
                     UserDirectoryOpen,
                     Dcb,
                     Ccb);

    /* Increase counters */
    Dcb->UncleanCount++;
    Dcb->OpenCount++;
    Vcb->OpenFileCount++;
    if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++;

    /* Set delete on close */
    if (DeleteOnClose)
        SetFlag(Ccb->Flags, CCB_DELETE_ON_CLOSE);

    /* Clear delay close flag */
    ClearFlag(Dcb->State, FCB_STATE_DELAY_CLOSE);

    /* That's it */
    Iosb.Status = STATUS_SUCCESS;
    Iosb.Information = FILE_OPENED;

    /* Release the lock */
    FatReleaseFcb(IrpContext, Dcb);

    return Iosb;
}
Exemplo n.º 2
0
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
    UINT32 GrantedAccess, UINT32 ShareAccess, NTSTATUS *PResult)
{
    /*
     * Attempt to insert our FileNode into the volume device's generic table.
     * If an FileNode with the same UserContext already exists, then use that
     * FileNode instead.
     *
     * There is no FileNode that can be acquired when calling this function.
     */

    PAGED_CODE();

    PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
    FSP_FILE_NODE *OpenedFileNode;
    BOOLEAN Inserted, DeletePending;
    NTSTATUS Result;

    FspFsvolDeviceLockContextTable(FsvolDeviceObject);

    OpenedFileNode = FspFsvolDeviceInsertContextByName(FsvolDeviceObject,
        &FileNode->FileName, FileNode, &FileNode->ContextByNameElementStorage, &Inserted);
    ASSERT(0 != OpenedFileNode);

    if (Inserted)
    {
        /*
         * The new FileNode was inserted into the Context table. Set its share access
         * and reference and open it. There should be (at least) two references to this
         * FileNode, one from our caller and one from the Context table.
         */
        ASSERT(OpenedFileNode == FileNode);

        IoSetShareAccess(GrantedAccess, ShareAccess, FileObject,
            &OpenedFileNode->ShareAccess);
    }
    else
    {
        /*
         * The new FileNode was NOT inserted into the Context table. Instead we are
         * opening a prior FileNode that we found in the table.
         */
        ASSERT(OpenedFileNode != FileNode);

        DeletePending = 0 != OpenedFileNode->DeletePending;
        MemoryBarrier();
        if (DeletePending)
        {
            Result = STATUS_DELETE_PENDING;
            goto exit;
        }

        /*
         * FastFat says to do the following on Vista and above.
         *
         * Quote:
         *     Do an extra test for writeable user sections if the user did not allow
         *     write sharing - this is neccessary since a section may exist with no handles
         *     open to the file its based against.
         */
        if (!FlagOn(ShareAccess, FILE_SHARE_WRITE) &&
            FlagOn(GrantedAccess,
                FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE) &&
            MmDoesFileHaveUserWritableReferences(&OpenedFileNode->NonPaged->SectionObjectPointers))
        {
            Result = STATUS_SHARING_VIOLATION;
            goto exit;
        }

        /* share access check */
        Result = IoCheckShareAccess(GrantedAccess, ShareAccess, FileObject,
            &OpenedFileNode->ShareAccess, TRUE);

    exit:
        if (!NT_SUCCESS(Result))
        {
            if (0 != PResult)
                *PResult = Result;

            OpenedFileNode = 0;
        }
    }

    if (0 != OpenedFileNode)
    {
        FspFileNodeReference(OpenedFileNode);
        OpenedFileNode->OpenCount++;
        OpenedFileNode->HandleCount++;
    }

    FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);

    return OpenedFileNode;
}