static NTSTATUS
PvfsSetFileAllocationInfo(
    PPVFS_IRP_CONTEXT pIrpContext
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PIRP pIrp = pIrpContext->pIrp;
    PPVFS_CCB pCcb = NULL;
    IRP_ARGS_QUERY_SET_INFORMATION Args = {0};
    PPVFS_PENDING_SET_ALLOCATION pSetAllocationCtx = NULL;
    PFILE_ALLOCATION_INFORMATION pFileInfo = NULL;

    Args = pIrpContext->pIrp->Args.QuerySetInformation;
    pFileInfo = (PFILE_ALLOCATION_INFORMATION)Args.FileInformation;

    /* Sanity checks */

    ntError =  PvfsAcquireCCB(pIrp->FileHandle, &pCcb);
    BAIL_ON_NT_STATUS(ntError);

    BAIL_ON_INVALID_PTR(Args.FileInformation, ntError);

    if (Args.Length < sizeof(*pFileInfo))
    {
        ntError = STATUS_BUFFER_TOO_SMALL;
        BAIL_ON_NT_STATUS(ntError);
    }

    ntError = PvfsAccessCheckFileHandle(pCcb, FILE_WRITE_DATA);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsCreateSetAllocationContext(
                  &pSetAllocationCtx,
                  pIrpContext,
                  pCcb);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsOplockBreakIfLocked(pIrpContext, pCcb, pCcb->pFcb);

    switch (ntError)
    {
    case STATUS_SUCCESS:
        ntError = PvfsSetAllocationWithContext(pSetAllocationCtx);
        break;

    case STATUS_OPLOCK_BREAK_IN_PROGRESS:
        ntError = PvfsPendOplockBreakTest(
                      pSetAllocationCtx->pCcb->pFcb,
                      pIrpContext,
                      pSetAllocationCtx->pCcb,
                      PvfsSetAllocationWithContext,
                      PvfsFreeSetAllocationContext,
                      (PVOID)pSetAllocationCtx);
        if (ntError == STATUS_SUCCESS) {
            pSetAllocationCtx = NULL;
            ntError = STATUS_PENDING;
        }
        break;

    case STATUS_PENDING:
        ntError = PvfsAddItemPendingOplockBreakAck(
                      pSetAllocationCtx->pCcb->pFcb,
                      pIrpContext,
                      PvfsSetAllocationWithContext,
                      PvfsFreeSetAllocationContext,
                      (PVOID)pSetAllocationCtx);
        if (ntError == STATUS_SUCCESS) {
            pSetAllocationCtx = NULL;
            ntError = STATUS_PENDING;
        }
        break;
    }
    BAIL_ON_NT_STATUS(ntError);

cleanup:
    PvfsFreeSetAllocationContext((PVOID*)&pSetAllocationCtx);

    if (pCcb)
    {
        PvfsReleaseCCB(pCcb);
    }

    return ntError;

error:
    goto cleanup;
}
Esempio n. 2
0
static
NTSTATUS
PvfsReadInternal(
    PPVFS_IRP_CONTEXT pIrpContext
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PIRP pIrp = pIrpContext->pIrp;
    PPVFS_CCB pCcb = NULL;
    PPVFS_PENDING_READ pReadCtx = NULL;

    /* Sanity checks */

    ntError =  PvfsAcquireCCB(pIrp->FileHandle, &pCcb);
    BAIL_ON_NT_STATUS(ntError);

    if (PVFS_IS_DIR(pCcb)) {
        ntError = STATUS_FILE_IS_A_DIRECTORY;
        BAIL_ON_NT_STATUS(ntError);
    }

#if 0xFFFFFFFF > SSIZE_MAX
    if ((size_t)pIrp->Args.ReadWrite.Length > (size_t) SSIZE_MAX) {
        ntError = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntError);
    }
#endif

    /* Check the right permissions based on the PagingIo flag */

    if (pIrp->Args.ReadWrite.IsPagingIo)
    {
        ntError = PvfsAccessCheckAnyFileHandle(
                      pCcb,
                      FILE_READ_DATA|FILE_EXECUTE);
    }
    else
    {
        ntError = PvfsAccessCheckFileHandle(
                      pCcb,
                      FILE_READ_DATA);
    }
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsCreateReadContext(&pReadCtx, pIrpContext, pCcb);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsOplockBreakIfLocked(pIrpContext, pCcb, pCcb->pScb);

    switch (ntError)
    {
    case STATUS_SUCCESS:
        ntError = PvfsReadFileWithContext(pReadCtx);
        break;

    case STATUS_OPLOCK_BREAK_IN_PROGRESS:
        ntError = PvfsPendOplockBreakTest(
                      pReadCtx->pCcb->pScb,
                      pIrpContext,
                      pReadCtx->pCcb,
                      PvfsReadFileWithContext,
                      PvfsFreeReadContext,
                      (PVOID)pReadCtx);
        if (ntError == STATUS_PENDING)
        {
            pReadCtx = NULL;
        }
        break;

    case STATUS_PENDING:
        ntError = PvfsAddItemPendingOplockBreakAck(
                      pReadCtx->pCcb->pScb,
                      pIrpContext,
                      PvfsReadFileWithContext,
                      PvfsFreeReadContext,
                      (PVOID)pReadCtx);
        if (ntError == STATUS_PENDING)
        {
            pReadCtx = NULL;
        }
        break;
    }
    BAIL_ON_NT_STATUS(ntError);

cleanup:
    PvfsFreeReadContext(OUT_PPVOID(&pReadCtx));

    if (pCcb)
    {
        PvfsReleaseCCB(pCcb);
    }

    return ntError;

error:
    goto cleanup;
}