Пример #1
0
static NTSTATUS
PvfsQueryFilePositionInfo(
    PPVFS_IRP_CONTEXT pIrpContext
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PIRP pIrp = pIrpContext->pIrp;
    PPVFS_CCB pCcb = NULL;
    PFILE_POSITION_INFORMATION pFileInfo = NULL;
    IRP_ARGS_QUERY_SET_INFORMATION Args = pIrpContext->pIrp->Args.QuerySetInformation;
    off_t CurrentOffset = 0;

    /* Sanity checks */

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

    BAIL_ON_INVALID_PTR(Args.FileInformation, ntError);

    ntError = PvfsAccessCheckAnyFileHandle(
                  pCcb,
                  (FILE_READ_DATA|FILE_WRITE_DATA));
    BAIL_ON_NT_STATUS(ntError);

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

    pFileInfo = (PFILE_POSITION_INFORMATION)Args.FileInformation;

    /* Real work starts here */

    /* Position */
    ntError = PvfsSysLseek(pCcb->fd, 0, SEEK_CUR, &CurrentOffset);
    BAIL_ON_NT_STATUS(ntError);

    pFileInfo->CurrentByteOffset = CurrentOffset;

    pIrp->IoStatusBlock.BytesTransferred = sizeof(*pFileInfo);
    ntError = STATUS_SUCCESS;

cleanup:

    if (pCcb) {
        PvfsReleaseCCB(pCcb);
    }

    return ntError;

error:
    goto cleanup;
}
Пример #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;
}