コード例 #1
0
ファイル: notify.c プロジェクト: bhanug/likewise-open
static
NTSTATUS
PvfsNotifyAllocateFilter(
    PPVFS_NOTIFY_FILTER_RECORD *ppNotifyRecord,
    PPVFS_IRP_CONTEXT pIrpContext,
    PPVFS_CCB pCcb,
    FILE_NOTIFY_CHANGE NotifyFilter,
    BOOLEAN bWatchTree
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_NOTIFY_FILTER_RECORD pFilter = NULL;

    ntError = PvfsAllocateMemory(
                  OUT_PPVOID(&pFilter),
                  sizeof(PVFS_NOTIFY_FILTER_RECORD),
                  TRUE);
    BAIL_ON_NT_STATUS(ntError);

    pFilter->pIrpContext = PvfsReferenceIrpContext(pIrpContext);
    pFilter->pCcb = PvfsReferenceCCB(pCcb);
    pFilter->NotifyFilter = NotifyFilter;
    pFilter->bWatchTree = bWatchTree;

    *ppNotifyRecord = pFilter;
    pFilter  = NULL;

cleanup:
    return ntError;

error:
    goto cleanup;
}
コード例 #2
0
static NTSTATUS
PvfsCreateSetAllocationContext(
    OUT PPVFS_PENDING_SET_ALLOCATION *ppSetAllocationContext,
    IN  PPVFS_IRP_CONTEXT pIrpContext,
    IN  PPVFS_CCB pCcb
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_PENDING_SET_ALLOCATION pSetAllocationCtx = NULL;

    ntError = PvfsAllocateMemory(
                  (PVOID*)&pSetAllocationCtx,
                  sizeof(PVFS_PENDING_READ));
    BAIL_ON_NT_STATUS(ntError);

    pSetAllocationCtx->pIrpContext = PvfsReferenceIrpContext(pIrpContext);
    pSetAllocationCtx->pCcb = PvfsReferenceCCB(pCcb);

    *ppSetAllocationContext = pSetAllocationCtx;

    ntError = STATUS_SUCCESS;

cleanup:
    return ntError;

error:
    goto cleanup;
}
コード例 #3
0
ファイル: irpctx.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
PvfsAllocateIrpContext(
	PPVFS_IRP_CONTEXT *ppIrpContext,
    PIRP pIrp
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_IRP_CONTEXT pIrpContext = NULL;

    *ppIrpContext = NULL;

    ntError = PvfsAllocateMemory((PVOID*)&pIrpContext,
                                 sizeof(PVFS_IRP_CONTEXT));
    BAIL_ON_NT_STATUS(ntError);

    pthread_mutex_init(&pIrpContext->Mutex, NULL);
    pIrpContext->RefCount = 1;

    pIrpContext->Flags = PVFS_IRP_CTX_FLAG_NONE;
    pIrpContext->QueueType = PVFS_QUEUE_TYPE_NONE;
    pIrpContext->pFcb = NULL;

    pIrpContext->pIrp = pIrp;

    *ppIrpContext = pIrpContext;

    InterlockedIncrement(&gPvfsIrpContextCount);

cleanup:
    return ntError;

error:
    goto cleanup;
}
コード例 #4
0
static
NTSTATUS
PvfsCreateSetEndOfFileContext(
    OUT PPVFS_PENDING_SET_END_OF_FILE *ppSetEndOfFileContext,
    IN  PPVFS_IRP_CONTEXT pIrpContext,
    IN  PPVFS_CCB pCcb
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_PENDING_SET_END_OF_FILE pSetEndOfFileCtx = NULL;

    ntError = PvfsAllocateMemory(
                  OUT_PPVOID(&pSetEndOfFileCtx),
                  sizeof(PVFS_PENDING_SET_END_OF_FILE),
                  TRUE);
    BAIL_ON_NT_STATUS(ntError);

    pSetEndOfFileCtx->pIrpContext = PvfsReferenceIrpContext(pIrpContext);
    pSetEndOfFileCtx->pCcb = PvfsReferenceCCB(pCcb);

    *ppSetEndOfFileContext = pSetEndOfFileCtx;

    ntError = STATUS_SUCCESS;

cleanup:
    return ntError;

error:
    goto cleanup;
}
コード例 #5
0
ファイル: wildcard.c プロジェクト: bhanug/likewise-open
static
NTSTATUS
PvfsWildcardStackPush(
    IN OUT PLW_LIST_LINKS pStack,
    IN PSTR pszInputString,
    IN PSTR pszPattern
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PPVFS_WILDCARD_STATE_ENTRY pState = NULL;

    ntError = PvfsAllocateMemory(OUT_PPVOID(&pState), sizeof(*pState), TRUE);
    BAIL_ON_NT_STATUS(ntError);

    pState->pszInputString = pszInputString;
    pState->pszPattern = pszPattern;

    LwListInsertAfter(pStack, &pState->StackLinks);

cleanup:
    return ntError;

error:
    goto cleanup;
}
コード例 #6
0
ファイル: alloc.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
PvfsReallocateMemory(
    IN OUT PVOID *ppBuffer,
    IN DWORD dwNewSize
    )
{
    NTSTATUS ntError = STATUS_INSUFFICIENT_RESOURCES;
    PVOID pBuffer = *ppBuffer;
    PVOID pNewBuffer;

    if (dwNewSize <= 0) {
        return STATUS_INVALID_PARAMETER;
    }

    /* Check for a simple malloc() */

    if (pBuffer == NULL)
    {
        return PvfsAllocateMemory(ppBuffer, dwNewSize);
    }


    if ((pNewBuffer = RtlMemoryRealloc(pBuffer, dwNewSize)) != NULL)
    {
        *ppBuffer = pNewBuffer;
        ntError = STATUS_SUCCESS;
    }

    return ntError;
}
コード例 #7
0
ファイル: notify.c プロジェクト: bhanug/likewise-open
VOID
PvfsNotifyScheduleFullReport(
    PPVFS_FCB pFcb,
    FILE_NOTIFY_CHANGE Filter,
    FILE_ACTION Action,
    PCSTR pszFilename
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_NOTIFY_REPORT_RECORD pReport = NULL;

    BAIL_ON_INVALID_PTR(pFcb, ntError);

    ntError = PvfsAllocateMemory(
                  OUT_PPVOID(&pReport),
                  sizeof(PVFS_NOTIFY_REPORT_RECORD),
                  FALSE);
    BAIL_ON_NT_STATUS(ntError);

    pReport->pFcb = PvfsReferenceFCB(pFcb);
    pReport->Filter = Filter;
    pReport->Action = Action;

    ntError = LwRtlCStringDuplicate(&pReport->pszFilename, pszFilename);
    BAIL_ON_NT_STATUS(ntError);

    ntError = LwRtlQueueWorkItem(
                  gPvfsDriverState.ThreadPool,
                  PvfsNotifyProcessEvent,
                  pReport,
                  0);
    BAIL_ON_NT_STATUS(ntError);

error:
    if (!NT_SUCCESS(ntError))
    {
        if (pReport)
        {
            PvfsNotifyFullReportCtxFree(&pReport);
        }
    }

    return;
}
コード例 #8
0
ファイル: read.c プロジェクト: bhanug/likewise-open
static
NTSTATUS
PvfsCreateReadContext(
    OUT PPVFS_PENDING_READ *ppReadContext,
    IN  PPVFS_IRP_CONTEXT pIrpContext,
    IN  PPVFS_CCB pCcb
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_PENDING_READ pReadCtx = NULL;

    ntError = PvfsAllocateMemory(
                  OUT_PPVOID(&pReadCtx),
                  sizeof(PVFS_PENDING_READ),
                  FALSE);
    BAIL_ON_NT_STATUS(ntError);

    pReadCtx->pZctContext = NULL;
    pReadCtx->pIrpContext = PvfsReferenceIrpContext(pIrpContext);
    pReadCtx->pCcb = PvfsReferenceCCB(pCcb);

    if (IRP_ZCT_OPERATION_PREPARE == pIrpContext->pIrp->Args.ReadWrite.ZctOperation)
    {
        ntError = PvfsCreateZctContext(
                        &pReadCtx->pZctContext,
                        pIrpContext,
                        pCcb);
        BAIL_ON_NT_STATUS(ntError);
    }

    *ppReadContext = pReadCtx;

    ntError = STATUS_SUCCESS;

cleanup:
    return ntError;

error:
    PvfsFreeReadContext(OUT_PPVOID(&pReadCtx));

    goto cleanup;
}
コード例 #9
0
ファイル: create.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
PvfsAllocateCreateContext(
    OUT PPVFS_PENDING_CREATE *ppCreate,
    IN  PPVFS_IRP_CONTEXT pIrpContext
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_PENDING_CREATE pCreateCtx = NULL;
    IRP_ARGS_CREATE Args = pIrpContext->pIrp->Args.Create;
    PIO_CREATE_SECURITY_CONTEXT pSecCtx = Args.SecurityContext;

    ntError = PvfsAllocateMemory(
                  (PVOID*)&pCreateCtx,
                  sizeof(PVFS_PENDING_CREATE));
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsCanonicalPathName(
                  &pCreateCtx->pszOriginalFilename,
                  Args.FileName);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsAllocateCCB(&pCreateCtx->pCcb);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsAcquireAccessToken(pCreateCtx->pCcb, pSecCtx);
    BAIL_ON_NT_STATUS(ntError);

    pCreateCtx->pIrpContext = PvfsReferenceIrpContext(pIrpContext);

    *ppCreate = pCreateCtx;
    pCreateCtx = NULL;


cleanup:
    return ntError;

error:
    PvfsFreeCreateContext((PVOID*)&pCreateCtx);

    goto cleanup;
}
コード例 #10
0
ファイル: notify.c プロジェクト: bhanug/likewise-open
static
NTSTATUS
PvfsNotifyAllocateChangeBuffer(
    PPVFS_NOTIFY_FILTER_BUFFER pBuffer,
    ULONG Length
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;

    ntError = PvfsAllocateMemory((PVOID*)&pBuffer->pData, Length, TRUE);
    BAIL_ON_NT_STATUS(ntError);

    pBuffer->Length = Length;

    pBuffer->Status = STATUS_SUCCESS;
    pBuffer->Offset = 0;
    pBuffer->pNotify = NULL;

cleanup:
    return ntError;

error:
    goto cleanup;
}
コード例 #11
0
ファイル: create.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
PvfsCreateDirDoSysOpen(
    IN PVOID pContext
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_PENDING_CREATE pCreateContext = (PPVFS_PENDING_CREATE)pContext;
    PIRP pIrp = pCreateContext->pIrpContext->pIrp;
    IRP_ARGS_CREATE Args = pIrp->Args.Create;
    int fd = -1;
    int unixFlags = 0;
    PIO_CREATE_SECURITY_CONTEXT pSecCtx = Args.SecurityContext;
    FILE_CREATE_RESULT CreateResult = 0;
    IO_MATCH_FILE_SPEC FileSpec = {0};
    WCHAR wszPattern[2] = {L'*', 0x0 };
    PIO_SECURITY_CONTEXT_PROCESS_INFORMATION pProcess = NULL;
    PBOOLEAN pbEnableAbe = NULL;
    ULONG ulEcpSize = 0;

    pProcess = IoSecurityGetProcessInfo(pSecCtx);

    /* Fail any create that requires setting the security but doesn't
       have the Unix uid/gid information */

    if ((pCreateContext->SetPropertyFlags & PVFS_SET_PROP_SECURITY) &&
        (pProcess == NULL))
    {
        ntError = STATUS_ACCESS_DENIED;
        BAIL_ON_NT_STATUS(ntError);
    }

    /* Do the open() */

    ntError = MapPosixOpenFlags(
                  &unixFlags,
                  pCreateContext->GrantedAccess,
                  Args);
    BAIL_ON_NT_STATUS(ntError);

    if (!pCreateContext->bFileExisted)
    {
        ntError = PvfsSysMkDir(
                      pCreateContext->pszDiskFilename,
                      (mode_t)gPvfsDriverConfig.CreateDirectoryMode);
        BAIL_ON_NT_STATUS(ntError);
    }

    /* Open the DIR* and then open a fd based on that */

    ntError = PvfsAllocateMemory(
                  (PVOID)&pCreateContext->pCcb->pDirContext,
                  sizeof(PVFS_DIRECTORY_CONTEXT));
    BAIL_ON_NT_STATUS(ntError);

    pCreateContext->pCcb->pszFilename = pCreateContext->pszDiskFilename;
    pCreateContext->pszDiskFilename = NULL;

    ntError = IoRtlEcpListFind(
                  pIrp->Args.Create.EcpList,
                  SRV_ECP_TYPE_ABE,
                  OUT_PPVOID(&pbEnableAbe),
                  &ulEcpSize);
    if (ntError != STATUS_NOT_FOUND)
    {
        BAIL_ON_NT_STATUS(ntError);

        if (ulEcpSize != sizeof(BOOLEAN))
        {
            ntError = STATUS_INVALID_PARAMETER;
            BAIL_ON_NT_STATUS(ntError);
        }

        if (*pbEnableAbe)
        {
            pCreateContext->pCcb->EcpFlags |= PVFS_ECP_ENABLE_ABE;
        }
    }

    do
    {
        ntError = PvfsSysOpen(
                      &fd,
                      pCreateContext->pCcb->pszFilename,
                      0,
                      0);

    } while (ntError == STATUS_MORE_PROCESSING_REQUIRED);
    BAIL_ON_NT_STATUS(ntError);

    /* Save our state */

    pCreateContext->pCcb->fd = fd;
    pCreateContext->pCcb->ShareFlags = Args.ShareAccess;
    pCreateContext->pCcb->AccessGranted = pCreateContext->GrantedAccess;
    pCreateContext->pCcb->CreateOptions = Args.CreateOptions;

    ntError = PvfsAddCCBToFCB(pCreateContext->pFcb, pCreateContext->pCcb);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsSaveFileDeviceInfo(pCreateContext->pCcb);
    BAIL_ON_NT_STATUS(ntError);

    if ((pCreateContext->SetPropertyFlags & PVFS_SET_PROP_SECURITY) && pSecCtx)
    {
        /* Unix Security */

        ntError = PvfsSysChown(
                      pCreateContext->pCcb,
                      pProcess->Uid,
                      pProcess->Gid);
        BAIL_ON_NT_STATUS(ntError);

        /* Security Descriptor */

        ntError = PvfsCreateFileSecurity(
                      pCreateContext->pCcb->pUserToken,
                      pCreateContext->pCcb,
                      Args.SecurityDescriptor,
                      TRUE);
        BAIL_ON_NT_STATUS(ntError);
    }

    if ((pCreateContext->SetPropertyFlags & PVFS_SET_PROP_ATTRIB) &&
        (Args.FileAttributes != 0))
    {
        ntError = PvfsSetFileAttributes(
                      pCreateContext->pCcb,
                      Args.FileAttributes);
        BAIL_ON_NT_STATUS(ntError);
    }

    /* Save the delete-on-close flag to the FCB */

    if (Args.CreateOptions & FILE_DELETE_ON_CLOSE)
    {
        LwRtlUnicodeStringInit(&FileSpec.Pattern, wszPattern);

        ntError = PvfsEnumerateDirectory(pCreateContext->pCcb, &FileSpec, 1, FALSE);
        if (ntError == STATUS_SUCCESS)
        {
            ntError = STATUS_DIRECTORY_NOT_EMPTY;
            BAIL_ON_NT_STATUS(ntError);
        }

        pCreateContext->pCcb->bPendingDeleteHandle = TRUE;
    }

    ntError = PvfsStoreCCB(pIrp->FileHandle, pCreateContext->pCcb);
    BAIL_ON_NT_STATUS(ntError);

    PvfsInitializeZctSupport(pCreateContext->pCcb, pIrp->FileHandle);

    CreateResult = PvfsSetCreateResult(
                       Args.CreateDisposition,
                       pCreateContext->bFileExisted,
                       STATUS_SUCCESS);

    if (CreateResult == FILE_CREATED)
    {
        PvfsNotifyScheduleFullReport(
            pCreateContext->pCcb->pFcb,
            FILE_NOTIFY_CHANGE_FILE_NAME,
            FILE_ACTION_ADDED,
            pCreateContext->pCcb->pszFilename);
    }

    /* The CCB has been handled off to the FileHandle so make sure
       we don't think we still own it */

    pCreateContext->pCcb = NULL;

cleanup:
    pIrp->IoStatusBlock.CreateResult = CreateResult;

    return ntError;

error:
    CreateResult = PvfsSetCreateResult(
                       Args.CreateDisposition,
                       pCreateContext->bFileExisted,
                       ntError);

    if (fd != -1)
    {
        PSTR pszRemovePath = NULL;

        /* Pick up where we started the pathname */

        pszRemovePath = pCreateContext->pszDiskFilename ?
                        pCreateContext->pszDiskFilename :
                        pCreateContext->pCcb->pszFilename;

        PvfsCleanupFailedCreate(
            fd,
            pszRemovePath,
            !pCreateContext->bFileExisted);
    }

    goto cleanup;
}
コード例 #12
0
ファイル: fcb.c プロジェクト: bhanug/likewise-open
NTSTATUS
PvfsAllocateFCB(
    PPVFS_FCB *ppFcb
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_FCB pFcb = NULL;

    *ppFcb = NULL;

    ntError = PvfsAllocateMemory(
                  OUT_PPVOID(&pFcb),
                  sizeof(*pFcb),
                  FALSE);
    BAIL_ON_NT_STATUS(ntError);

    PvfsInitializeCB(&pFcb->BaseControlBlock);

    /* Initialize mutexes and refcounts */

    pthread_rwlock_init(&pFcb->rwScbLock, NULL);

    /* List of Notify requests */

    ntError = PvfsListInit(
                  &pFcb->pNotifyListIrp,
                  PVFS_SCB_MAX_PENDING_NOTIFY,
                  (PPVFS_LIST_FREE_DATA_FN)PvfsFreeNotifyRecord);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsListInit(
                  &pFcb->pNotifyListBuffer,
                  PVFS_SCB_MAX_PENDING_NOTIFY,
                  (PPVFS_LIST_FREE_DATA_FN)PvfsFreeNotifyRecord);
    BAIL_ON_NT_STATUS(ntError);

    /* List of SCBs */

    ntError = PvfsListInit(
                  &pFcb->pScbList,
                  0,
                  (PPVFS_LIST_FREE_DATA_FN)PvfsFCBFreeSCB);
    BAIL_ON_NT_STATUS(ntError);


    /* Miscellaneous */

    PVFS_CLEAR_FILEID(pFcb->FileId);

    pFcb->LastWriteTime = 0;
    pFcb->OpenHandleCount = 0;
    pFcb->bDeleteOnClose = FALSE;
    pFcb->pParentFcb = NULL;
    pFcb->pszFilename = NULL;

    *ppFcb = pFcb;

    InterlockedIncrement(&gPvfsDriverState.Counters.Fcb);

    ntError = STATUS_SUCCESS;

cleanup:
    return ntError;

error:
    if (pFcb)
    {
        PvfsFreeFCB(pFcb);
    }

    goto cleanup;
}
コード例 #13
0
ファイル: ccb.c プロジェクト: bhanug/likewise-open
NTSTATUS
PvfsAllocateCCB(
    PPVFS_CCB *ppCCB
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_CCB pCCB = NULL;

    *ppCCB = NULL;

    ntError = PvfsAllocateMemory(
                  OUT_PPVOID(&pCCB),
                  sizeof(PVFS_CCB),
                  FALSE);
    BAIL_ON_NT_STATUS(ntError);

    InterlockedIncrement(&gPvfsDriverState.Counters.Ccb);

    /* Initialize mutexes and refcounts */

    pthread_mutex_init(&pCCB->ControlBlock, NULL);

    PVFS_INIT_LINKS(&pCCB->ScbList);

    pCCB->OplockState = PVFS_OPLOCK_STATE_NONE;
    pCCB->CurrentLeaseState = IO_LEASE_STATE_NONE;
    pCCB->NewLeaseState = IO_LEASE_STATE_NONE;

    pCCB->fd = -1;
    PVFS_CLEAR_FILEID(pCCB->FileId);

    pCCB->pScb = NULL;
    pCCB->pwszShareName = NULL;
    pCCB->pDirContext = NULL;
    pCCB->pUserToken = NULL;
    pCCB->ChangeEvent = 0;
    pCCB->WriteCount = 0;
    pCCB->FileSize = 0;
    pCCB->AccessGranted = 0;
    pCCB->Flags = PVFS_CCB_FLAG_NONE;

    LwRtlZeroMemory(&pCCB->LockTable, sizeof(pCCB->LockTable));

    ntError = PvfsListInit(
                  &pCCB->pZctContextList,
                  0,  /* no max size */
                  (PPVFS_LIST_FREE_DATA_FN)PvfsFreeZctContext);
    BAIL_ON_NT_STATUS(ntError);

    /* Add initial ref count */

    pCCB->RefCount = 1;

    *ppCCB = pCCB;

    ntError = STATUS_SUCCESS;

cleanup:
    return ntError;

error:
    if (pCCB)
    {
        PvfsFreeCCB(pCCB);
    }


    goto cleanup;
}
コード例 #14
0
ファイル: zct.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
PvfsCreateZctContext(
    OUT PPVFS_ZCT_CONTEXT *ppZctContext,
    IN  PPVFS_IRP_CONTEXT pIrpContext,
    IN  PPVFS_CCB pCcb
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_ZCT_CONTEXT pZctContext = NULL;
    PVFS_ZCT_MODE ZctMode = gPvfsDriverConfig.ZctMode;

    if (IRP_ZCT_OPERATION_PREPARE != pIrpContext->pIrp->Args.ReadWrite.ZctOperation)
    {
        ntError = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntError);
    }

    switch (ZctMode)
    {
    case PVFS_ZCT_MODE_MEMORY:
#ifdef HAVE_SPLICE
    case PVFS_ZCT_MODE_SPLICE:
#endif
        break;
    default:
        /* So the I/O does a backoff to non-ZCT */
        ntError = STATUS_NOT_SUPPORTED;
        BAIL_ON_NT_STATUS(ntError);
    }

    ntError = PvfsAllocateMemory(
                  (PVOID*)&pZctContext,
                  sizeof(*pZctContext));
    BAIL_ON_NT_STATUS(ntError);

    pZctContext->Mode = ZctMode;
    switch (pZctContext->Mode)
    {
    case PVFS_ZCT_MODE_MEMORY:
        ntError = PvfsAllocateMemory(
                      OUT_PPVOID(&pZctContext->pBuffer),
                      pIrpContext->pIrp->Args.ReadWrite.Length);
        BAIL_ON_NT_STATUS(ntError);
        break;
#ifdef HAVE_SPLICE
    case PVFS_ZCT_MODE_SPLICE:
        if (pIrpContext->pIrp->Args.ReadWrite.Length > SPLICE_PIPE_BUFFER_SIZE)
        {
            ntError = STATUS_NOT_SUPPORTED;
            BAIL_ON_NT_STATUS(ntError);
        }

        // TODO: Convert to using pipe2 (Linux).
        ntError = PvfsSysPipe(pZctContext->PipeFds);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysSetNonBlocking(pZctContext->PipeFds[0]);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysSetNonBlocking(pZctContext->PipeFds[1]);
        BAIL_ON_NT_STATUS(ntError);
        break;
#endif
    default:
        // can never happen
        ntError = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntError);
    }

    pZctContext->pCcb = PvfsReferenceCCB(pCcb);

    ntError = STATUS_SUCCESS;

cleanup:
    *ppZctContext = pZctContext;

    return ntError;

error:
    /* Backoff to non-ZCT because could not allocate resources */
    ntError = STATUS_NOT_SUPPORTED;

    PvfsFreeZctContext(&pZctContext);
    goto cleanup;
}
コード例 #15
0
ファイル: util_dir.c プロジェクト: bhanug/likewise-open
NTSTATUS
PvfsEnumerateDirectory(
    PPVFS_CCB pCcb,
    PIO_MATCH_FILE_SPEC pFileSpec,
    LONG Count,
    BOOLEAN bRescan
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    DIR *pDir = NULL;
    struct dirent *pDirEntry = NULL;
    struct dirent dirEntry = { 0 };
    PSTR pszPattern = NULL;
    BOOLEAN bCaseSensitive = FALSE;
    PSTR pszDiskFilename = NULL;
    PVFS_STAT Stat = { 0 };
    PSTR pszResolvedDirname = NULL;
    PSTR pszResolvedFilename = NULL;

    if (Count == 0)
    {
        ntError = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntError);
    }

    ntError = AllocateCStringFileSpec(&pszPattern, pFileSpec);
    BAIL_ON_NT_STATUS(ntError);

    if (bRescan)
    {
        if (pCcb->pDirContext->pDir)
        {
            PvfsSysCloseDir(pCcb->pDirContext->pDir);

        }
        PvfsFreeDirectoryContext(pCcb->pDirContext);
        pCcb->pDirContext = NULL;

        ntError = PvfsAllocateMemory(
                      (PVOID)&pCcb->pDirContext,
                      sizeof(PVFS_DIRECTORY_CONTEXT),
                      TRUE);
        BAIL_ON_NT_STATUS(ntError);

        pCcb->pDirContext->bScanned = FALSE;
    }


    if (!pCcb->pDirContext->bScanned)
    {
        if (!strchr(pszPattern, '?') && !strchr(pszPattern, '*'))
        {
            // A single file name match is the equivalent of a Windows Stat()
            ntError = PvfsLookupFile(
                          &pszDiskFilename,
                          &Stat,
                          pCcb->pScb->pOwnerFcb->pszFilename,
                          pszPattern,
                          pFileSpec->Options & IO_NAME_OPTION_CASE_SENSITIVE);
            BAIL_ON_NT_STATUS(ntError);

            ntError = PvfsFileSplitPath(
                          &pszResolvedDirname,
                          &pszResolvedFilename,
                          pszDiskFilename);
            BAIL_ON_NT_STATUS(ntError);

            if (IsSetFlag(pCcb->Flags, PVFS_CCB_FLAG_ENABLE_ABE))
            {
                ntError = PvfsAccessCheckFileEnumerate(
                              pCcb,
                              pszResolvedFilename);
                BAIL_ON_NT_STATUS(ntError);
            }

            ntError = PvfsDirContextAddEntry(
                          pCcb->pDirContext,
                          pszResolvedFilename);
            BAIL_ON_NT_STATUS(ntError);

            pCcb->pDirContext->bScanned = TRUE;

            // Success
            goto cleanup;
        }
        else
        {
            // Prepare to enumerate the entire directory
            ntError = PvfsSysOpenDir(
                          pCcb->pScb->pOwnerFcb->pszFilename,
                          &pCcb->pDirContext->pDir);
            BAIL_ON_NT_STATUS(ntError);

            pCcb->pDirContext->bScanned = TRUE;
        }
    }

    /* Loop to read entries */

    pDir = pCcb->pDirContext->pDir;

    /* -1 means to fill in whatever you can including current and
       parent directory entries */

    if (Count == -1)
    {
        /* Always add '.' and '..' first if thet match */

        if (PvfsWildcardMatch(".", pszPattern, FALSE))
        {
            ntError = PvfsDirContextAddEntry(pCcb->pDirContext, ".");
            BAIL_ON_NT_STATUS(ntError);
        }
        if (PvfsWildcardMatch("..", pszPattern, FALSE))
        {
            ntError = PvfsDirContextAddEntry(pCcb->pDirContext, "..");
            BAIL_ON_NT_STATUS(ntError);
        }
    }

    /* Loop through directory entries */

    for(ntError = PvfsSysReadDir(pDir, &dirEntry, &pDirEntry);
        pDirEntry && ((Count == -1) || (pCcb->pDirContext->dwNumEntries < Count));
        ntError = PvfsSysReadDir(pDir, &dirEntry, &pDirEntry))
    {
        /* First check the error return */
        BAIL_ON_NT_STATUS(ntError);

        /* We've already added the "." and ".." directories */

        if (RtlCStringIsEqual(pDirEntry->d_name, ".", FALSE) ||
            RtlCStringIsEqual(pDirEntry->d_name, "..", FALSE))
        {
            continue;
        }

        if (PvfsWildcardMatch(pDirEntry->d_name, pszPattern, bCaseSensitive))
        {
            if (IsSetFlag(pCcb->Flags, PVFS_CCB_FLAG_ENABLE_ABE))
            {
                ntError = PvfsAccessCheckFileEnumerate(
                              pCcb,
                              pDirEntry->d_name);
                if (ntError != STATUS_SUCCESS)
                {
                    continue;
                }
            }

            ntError = PvfsDirContextAddEntry(pCcb->pDirContext, pDirEntry->d_name);
            BAIL_ON_NT_STATUS(ntError);
        }
    }

    /* Bail if there were no matches */

    if (pCcb->pDirContext->dwNumEntries == 0) {
        ntError = STATUS_NO_SUCH_FILE;
        BAIL_ON_NT_STATUS(ntError);
    }

cleanup:
    RtlCStringFree(&pszResolvedFilename);
    RtlCStringFree(&pszResolvedDirname);
    RtlCStringFree(&pszDiskFilename);
    RtlCStringFree(&pszPattern);

    return ntError;

error:
    goto cleanup;
}