Esempio n. 1
0
NTSTATUS
PvfsFileBasename(
    PSTR *ppszFilename,
    PCSTR pszPath
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PSTR pszCursor = NULL;

    if ((pszCursor = strrchr(pszPath, '/')) != NULL)
    {
        /* Assume there is never a trailing '/' since that should
           be handled by PvfsCanonicalPathName() */

        pszCursor++;
    }

    if (pszCursor != NULL) {
        ntError = RtlCStringDuplicate(ppszFilename, pszCursor);
    } else {
        ntError = RtlCStringDuplicate(ppszFilename, pszPath);
    }
    BAIL_ON_NT_STATUS(ntError);

cleanup:
    return ntError;

error:
    goto cleanup;
}
Esempio n. 2
0
NTSTATUS
LwRtlAnsiStringAllocateFromUnicodeString(
    OUT PANSI_STRING pNewString,
    IN PUNICODE_STRING pString
    )
{
    NTSTATUS status = 0;
    PSTR pszNewString = NULL;
    ANSI_STRING newString = { 0 };

    status = RtlCStringDuplicate(&pszNewString, pszString);
    GOTO_CLEANUP_ON_STATUS(status);

    newString.Buffer = pszNewString;
    pszNewString = 0;
    newString.Length = wc16slen(newString.Buffer) * sizeof(newString.Buffer[0]);
    newString.MaximumLength = newString.Length + sizeof(newString.Buffer[0]);

cleanup:
    if (status)
    {
        RtlCStringFree(&pszNewString);
        RtlAnsiStringFree(&newString);
    }

    *pString = newString;

    return status;
}
Esempio n. 3
0
NTSTATUS
LwRtlAnsiStringAllocateFromCString(
    OUT PANSI_STRING pNewString,
    IN PCSTR pszString
    )
{
    NTSTATUS status = 0;
    PSTR pszNewString = NULL;
    ANSI_STRING newString = { 0 };

    status = RtlCStringDuplicate(&pszNewString, pszString);
    GOTO_CLEANUP_ON_STATUS(status);

    status = LwRtlAnsiStringInitEx(&newString, pszNewString);
    GOTO_CLEANUP_ON_STATUS(status);

    pszNewString = 0;

cleanup:
    if (status)
    {
        RtlCStringFree(&pszNewString);
        RtlAnsiStringFree(&newString);
    }

    *pNewString = newString;

    return status;
}
Esempio n. 4
0
static
NTSTATUS
AllocateCStringFileSpec(
    PSTR *ppszPattern,
    PIO_MATCH_FILE_SPEC pFileSpec
    )
{
    NTSTATUS ntError = STATUS_INSUFFICIENT_RESOURCES;


    if (pFileSpec == NULL)
    {
        ntError = RtlCStringDuplicate(ppszPattern, "*");
        BAIL_ON_NT_STATUS(ntError);

        goto cleanup;
    }

    ntError = RtlCStringAllocateFromUnicodeString(ppszPattern,
                                                  &pFileSpec->Pattern);
    BAIL_ON_NT_STATUS(ntError);

cleanup:
    return ntError;

error:
    goto cleanup;
}
Esempio n. 5
0
NTSTATUS
PvfsFileDirname(
    PSTR *ppszDirname,
    PCSTR pszPath
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PSTR pszCursor = NULL;
    PSTR pszNewString = NULL;

    /* Case #1: No '/' so just return '.' */
    if (((pszCursor = strrchr(pszPath, '/')) == NULL))
    {
        ntError = RtlCStringDuplicate(ppszDirname, ".");
        goto cleanup;
    }

    /* Case #2: only one '/' (at beginning of path) */

    if (pszCursor == pszPath) {
        ntError = RtlCStringDuplicate(ppszDirname, "/");
        goto cleanup;
    }

    /* Case #3: Real dirname and file name components */

    ntError = RTL_ALLOCATE(&pszNewString, CHAR,
                           PVFS_PTR_DIFF(pszPath,pszCursor) + 1);
    BAIL_ON_NT_STATUS(ntError);

    RtlCopyMemory(pszNewString, pszPath, PVFS_PTR_DIFF(pszPath,pszCursor));

    *ppszDirname = pszNewString;
    ntError = STATUS_SUCCESS;

cleanup:
    return ntError;

error:
    goto cleanup;
}
Esempio n. 6
0
NTSTATUS
PvfsDirContextAddEntry(
    PPVFS_DIRECTORY_CONTEXT pDirCtx,
    PCSTR pszPathname
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    DWORD dwCurrent = 0;
    PPVFS_DIRECTORY_ENTRY pList = NULL;

    if ((pDirCtx->ulAllocated == 0) ||
        ((pDirCtx->dwNumEntries+1) == pDirCtx->ulAllocated))
    {
        pDirCtx->ulAllocated += 256;
        ntError = PvfsReallocateMemory(
                      OUT_PPVOID(&pDirCtx->pDirEntries),
                      sizeof(PVFS_DIRECTORY_ENTRY)*pDirCtx->ulAllocated);
        BAIL_ON_NT_STATUS(ntError);
    }

    dwCurrent = pDirCtx->dwNumEntries;
    pList = pDirCtx->pDirEntries;

    pList[dwCurrent].bValidStat = FALSE;
    ntError = RtlCStringDuplicate(&pList[dwCurrent].pszFilename, pszPathname);
    BAIL_ON_NT_STATUS(ntError);


    pDirCtx->dwNumEntries++;
    ntError = STATUS_SUCCESS;

cleanup:
    return ntError;

error:
    goto cleanup;
}
Esempio n. 7
0
BOOLEAN
PvfsWildcardMatch(
    IN PSTR pszPathname,
    IN PSTR pszPattern,
    IN BOOLEAN bCaseSensitive
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PSTR pszString = NULL;
    PSTR pszMatch  = NULL;
    PSTR pszPathUpper = NULL;
    PSTR pszPatternUpper = NULL;
    BOOLEAN bMatched = FALSE;

    /* Quick check for an exact match */

    if (!strchr(pszPattern, '?') && !strchr(pszPattern, '*'))
    {
        return RtlCStringIsEqual(pszPathname, pszPattern, bCaseSensitive);
    }

    /* If we have a case insensitive search, upper case the
       Pathname and Pattern for easier comparison */

    pszString = pszPathname;
    pszMatch = pszPattern;

    if (!bCaseSensitive) {
        ntError = RtlCStringDuplicate(&pszPathUpper, pszPathname);
        BAIL_ON_NT_STATUS(ntError);

        ntError = RtlCStringDuplicate(&pszPatternUpper, pszPattern);
        BAIL_ON_NT_STATUS(ntError);

        PvfsCStringUpper(pszPathUpper);
        PvfsCStringUpper(pszPatternUpper);

        pszString = pszPathUpper;
        pszMatch  = pszPatternUpper;
    }


    /* Enter state machine */


    for (/* already performed init */;
         PVFS_CSTRING_NON_NULL(pszString) && PVFS_CSTRING_NON_NULL(pszMatch);
         pszString++)
    {
        PVFS_WILDCARD_TYPE eState = 0;
        CHAR cSrc = '\0';
        CHAR cMatch = '\0';
        DWORD dwCount = 0;

        /* Save the current CHAR */

        cSrc = *pszString;
        cMatch = *pszMatch;

        /* Consumes the pattern from pszMatch */

        eState = NextMatchState(&pszMatch, &dwCount);

        switch (eState) {
        case PVFS_WILDCARD_TYPE_NONE:
            if (cSrc != cMatch) {
                ntError = STATUS_NO_MATCH;
                BAIL_ON_NT_STATUS(ntError);
            }
            break;

        case PVFS_WILDCARD_TYPE_SPLAT:
        {
            PSTR pszCursor = NULL;

            /* We are done if this is the last character
               in the pattern */
            if (!PVFS_CSTRING_NON_NULL(pszMatch)) {
                pszString = NULL;
                goto cleanup;
            }

            /* If we don't find a match for the next character
               in the pattern, then fail */
            if ((pszCursor = strchr(pszString, *pszMatch)) == NULL) {
                ntError = STATUS_NO_MATCH;
                BAIL_ON_NT_STATUS(ntError);
            }

            /* Have to consume at least one character here */
            if (pszString == pszCursor) {
                ntError = STATUS_NO_MATCH;
                BAIL_ON_NT_STATUS(ntError);
            }
            /* Set to the previous character so that pszString is
               incremented properly next pass of the loop */
            pszString = pszCursor-1;

            break;
        }

        case PVFS_WILDCARD_TYPE_SINGLE:
        {
            DWORD i = 0;

            /* Consume dwCount characters */
            for (i=0;
                 i<dwCount && PVFS_CSTRING_NON_NULL(pszString);
                 i++, pszString++)
            {
                /* no loop body */;
            }
            if (*pszString == '\0') {
                /* backup so pszString incrent in outer loop
                   works out */
                pszString--;
            }
            break;
        }

        case PVFS_WILDCARD_TYPE_DOT:
            /* For now deal with the '.' as just another character */
            if (cSrc != cMatch) {
                ntError = STATUS_NO_MATCH;
                BAIL_ON_NT_STATUS(ntError);
            }
            break;

        case PVFS_WILDCARD_TYPE_SPLAT_DOT:
        {
            PSTR pszCursor = NULL;

            /* Similar to "A*B" except we search for the '.' from
               the end. */

            if ((pszCursor = strrchr(pszString, '.')) == NULL) {
                ntError = STATUS_NO_MATCH;
                BAIL_ON_NT_STATUS(ntError);
            }
            pszString = pszCursor;

            break;
        }

        case PVFS_WILDCARD_TYPE_SINGLE_DOT:
        {
            DWORD i = 0;

            /* We can match 0 - dwCount characters up to the last '.'
               This is really a hold over from DOS 8.3 filenames */

            for (i=0;
                 i<dwCount && PVFS_CSTRING_NON_NULL(pszString) && (*pszString != '.');
                 i++, pszString++)
            {
                /* no loop body */;
            }

            /* If we any path lefft, it better be on '.' for a match */

            if (pszString && *pszString != '.') {
                ntError = STATUS_NO_MATCH;
                BAIL_ON_NT_STATUS(ntError);
            }

            break;
        }

        }
    }

cleanup:
    /* We matched if pszString is empty AND either pszMatch is empty
       OR only contains wildcard characters */

    if (!PVFS_CSTRING_NON_NULL(pszString) &&
        (!PVFS_CSTRING_NON_NULL(pszMatch) ||
         (!strchr(pszPattern, '?') && !strchr(pszPattern, '*'))))
    {
        bMatched = TRUE;
    }

    if (!bCaseSensitive)
    {
        PVFS_FREE(&pszPathUpper);
        PVFS_FREE(&pszPatternUpper);
    }


    /* If we have any string left to parse, we don't
       have a match */

    return bMatched;

error:
    goto cleanup;
}
Esempio n. 8
0
NTSTATUS
PvfsCreateFCB(
    OUT PPVFS_FCB *ppFcb,
    IN PCSTR pszFilename,
    IN BOOLEAN bCheckShareAccess,
    IN FILE_SHARE_FLAGS SharedAccess,
    IN ACCESS_MASK DesiredAccess
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_FCB pFcb = NULL;
    BOOLEAN bBucketLocked = FALSE;
    PPVFS_CB_TABLE_ENTRY pBucket = NULL;
    PPVFS_FCB pParentFcb = NULL;

    ntError = PvfsFindParentFCB(&pParentFcb, pszFilename);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsCbTableGetBucket(&pBucket, &gPvfsDriverState.FcbTable, (PVOID)pszFilename);
    BAIL_ON_NT_STATUS(ntError);

    /* Protect against adding a duplicate */

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bBucketLocked, &pBucket->rwLock);

    ntError = PvfsCbTableLookup_inlock(
                  (PPVFS_CONTROL_BLOCK*)OUT_PPVOID(&pFcb),
                  pBucket,
                  pszFilename);
    if (ntError == STATUS_SUCCESS)
    {
        LWIO_UNLOCK_RWMUTEX(bBucketLocked, &pBucket->rwLock);

        /* If we have success, then we are good.  If we have a sharing
           violation, give the caller a chance to break the oplock and
           we'll try again when the create is resumed. */

        if (ntError == STATUS_SUCCESS ||
            ntError == STATUS_SHARING_VIOLATION)
        {
            *ppFcb = PvfsReferenceFCB(pFcb);
        }

        goto cleanup;
    }

    ntError = PvfsAllocateFCB(&pFcb);
    BAIL_ON_NT_STATUS(ntError);

    ntError = RtlCStringDuplicate(&pFcb->pszFilename, pszFilename);
    BAIL_ON_NT_STATUS(ntError);

    pFcb->pParentFcb = pParentFcb ? PvfsReferenceFCB(pParentFcb) : NULL;

    // New FCB so BaseControlBlock.Mutext locking is not necessary

    ntError = PvfsCbTableAdd_inlock(
                  pBucket,
                  pFcb->pszFilename,
                  (PPVFS_CONTROL_BLOCK)pFcb);
    BAIL_ON_NT_STATUS(ntError);

    /* Return a reference to the FCB */

    *ppFcb = PvfsReferenceFCB(pFcb);

cleanup:
    LWIO_UNLOCK_RWMUTEX(bBucketLocked, &pBucket->rwLock);

    if (pParentFcb)
    {
        PvfsReleaseFCB(&pParentFcb);
    }

    if (pFcb)
    {
        PvfsReleaseFCB(&pFcb);
    }

    return ntError;

error:
    goto cleanup;
}
Esempio n. 9
0
BOOLEAN
PvfsWildcardMatch(
    IN PSTR pszPathname,
    IN PSTR pszPattern,
    IN BOOLEAN bCaseSensitive
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PSTR pszString = NULL;
    PSTR pszMatch  = NULL;
    PSTR pszPathUpper = NULL;
    PSTR pszPatternUpper = NULL;
    BOOLEAN bMatched = FALSE;
    LW_LIST_LINKS Stack;

    // Quick check for an exact match

    if (!strchr(pszPattern, '?') && !strchr(pszPattern, '*'))
    {
        return RtlCStringIsEqual(pszPathname, pszPattern, bCaseSensitive);
    }

    // If we have a case insensitive search, upper case the Pathname
    // and Pattern for easier comparison

    pszString = pszPathname;
    pszMatch = pszPattern;

    if (!bCaseSensitive) {
        ntError = RtlCStringDuplicate(&pszPathUpper, pszPathname);
        BAIL_ON_NT_STATUS(ntError);

        ntError = RtlCStringDuplicate(&pszPatternUpper, pszPattern);
        BAIL_ON_NT_STATUS(ntError);

        PvfsCStringUpper(pszPathUpper);
        PvfsCStringUpper(pszPatternUpper);

        pszString = pszPathUpper;
        pszMatch  = pszPatternUpper;
    }


    // Enter state machine

    LwListInit(&Stack);

reset_state:
    while (PVFS_CSTRING_NON_NULL(pszString) && PVFS_CSTRING_NON_NULL(pszMatch))
    {
        PVFS_WILDCARD_TYPE eState = 0;
        CHAR cSrc = '\0';
        CHAR cMatch = '\0';
        DWORD dwCount = 0;

        // Save the current CHAR

        cSrc = *pszString;
        cMatch = *pszMatch;


        // Certain characters should never match and hence allow us to filter
        // certain file patterns

        if (cSrc == PVFS_STREAM_DELIMINATOR_C)
        {
            bMatched = FALSE;
            goto cleanup;
        }

        // Consumes the pattern from pszMatch

        eState = NextMatchState(&pszMatch, &dwCount);

        switch (eState)
        {
        case PVFS_WILDCARD_TYPE_NONE:
            if (cSrc != cMatch)
            {
                ntError = STATUS_NO_MATCH;
                pszString = NULL;
            }
            else
            {
                pszString++;
            }
            break;

        case PVFS_WILDCARD_TYPE_SPLAT:
        {
            // We are done if this is the last character in the pattern
            if (!PVFS_CSTRING_NON_NULL(pszMatch))
            {
                pszString = NULL;
            }
            else
            {
                // Be greedy - Consume as much of the string using the '*'
                // as possible.  This will require a stack in order to backtrack
                // on a failure.
                pszString = PvfsWildcardEatString(pszString, pszMatch);
                if (!pszString)
                {
                    ntError = STATUS_NO_MATCH;
                }
                else
                {
                    // Add next character past "String" match and the previously
                    // match "Pattern" state (so we pick up the '*' when we pop
                    // the stack
                    ntError = PvfsWildcardStackPush(
                                  &Stack,
                                  pszString+1,
                                  pszMatch-1);
                    BAIL_ON_NT_STATUS(ntError);
                }
            }
            break;
        }

        case PVFS_WILDCARD_TYPE_SINGLE:
        {
            DWORD i = 0;

            // Consume dwCount characters
            for (i=0;
                 (i<dwCount) && PVFS_CSTRING_NON_NULL(pszString);
                 i++, pszString++)
            {
                // no loop body
                ;
            }
            break;
        }

        case PVFS_WILDCARD_TYPE_DOT:
            // For now deal with the '.' as just another character
            if (cSrc != cMatch)
            {
                ntError = STATUS_NO_MATCH;
                pszString = NULL;
            }
            else
            {
                pszString++;
            }

            break;

        case PVFS_WILDCARD_TYPE_SPLAT_DOT:
        {
            PSTR pszCursor = NULL;

            // Similar to "A*B" except we search for the '.' from the end

            if ((pszCursor = strrchr(pszString, '.')) == NULL)
            {
                ntError = STATUS_NO_MATCH;
                pszString = NULL;
            }
            else
            {
                pszString = pszCursor + 1;
            }
            break;
        }

        case PVFS_WILDCARD_TYPE_SINGLE_DOT:
        {
            DWORD i = 0;

            // We can match 0 - dwCount characters up to the last '.'
            // This is really a hold over from DOS 8.3 filenames

            for (i=0;
                 i<dwCount && PVFS_CSTRING_NON_NULL(pszString) && (*pszString != '.');
                 i++, pszString++)
            {
                // no loop body
                ;
            }

            // If we any path left, it better be on '.' for a match

            if (*pszString == '.')
            {
                pszString++;
            }
            else
            {
                ntError = STATUS_NO_MATCH;
                pszString = NULL;
            }

            break;
        }

        }    // end of switch {...}
    }        // end of for {...}

    // We matched if pszString is empty AND either pszMatch is empty
    // OR only contains wildcard characters

    if ((ntError == STATUS_SUCCESS) &&
        !PVFS_CSTRING_NON_NULL(pszString) &&
        (!PVFS_CSTRING_NON_NULL(pszMatch) ||
         PvfsCStringOnlyContainsChars(pszMatch, "?*")))
    {
        bMatched = TRUE;
    }
    else if (!LwListIsEmpty(&Stack))
    {
        // Pop back to the earlier state, consume one character (*from '*')
        // and try another path
        ntError = PvfsWildcardStackPop(&Stack, &pszString, &pszMatch);
        BAIL_ON_NT_STATUS(ntError);

        pszString++;
        goto reset_state;
    }


cleanup:

    PvfsWildcardStackDestroy(&Stack);

    if (!bCaseSensitive)
    {
        PVFS_FREE(&pszPathUpper);
        PVFS_FREE(&pszPatternUpper);
    }

    // If we have any string left to parse, we don't have a match

    return bMatched;

error:
    goto cleanup;
}
Esempio n. 10
0
static NTSTATUS
PvfsResolvePath(
    PSTR *ppszResolvedPath,
    PCSTR pszLookupPath
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PSTR pszCursor = NULL;
    PSTR pszComponent = NULL;
    PSTR pszPath = NULL;
    PVFS_STAT Stat = {0};
    PSTR pszResolvedPath = NULL;
    PSTR pszResWorkingPath = NULL;
    PSTR pszWorkingPath = NULL;
    DWORD Length = PATH_MAX;
    DIR *pDir = NULL;
    struct dirent *pDirEntry = NULL;

    if (*pszLookupPath != '/') {
        ntError = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntError);
    }

    ntError = RTL_ALLOCATE(&pszResolvedPath, CHAR, Length);
    BAIL_ON_NT_STATUS(ntError);

    ntError = RTL_ALLOCATE(&pszWorkingPath, CHAR, PATH_MAX);
    BAIL_ON_NT_STATUS(ntError);

    ntError = RtlCStringDuplicate(&pszPath, pszLookupPath);
    BAIL_ON_NT_STATUS(ntError);

    pszComponent = pszPath + 1;

    while (pszComponent && (Length > 0))
    {
        pDir = NULL;

        if ((pszCursor = strchr(pszComponent, '/')) != NULL) {
            *pszCursor = '\0';
        }

        snprintf(pszWorkingPath, PATH_MAX-1, "%s/%s",
                 pszResolvedPath, pszComponent);

        /* Try cache first */

        ntError = PvfsPathCacheLookup(&pszResWorkingPath, pszWorkingPath);
        if(ntError == STATUS_SUCCESS)
        {
            strncpy(pszResolvedPath, pszResWorkingPath, PATH_MAX-1);
            Length = PATH_MAX - RtlCStringNumChars(pszResolvedPath);
            RtlCStringFree(&pszResWorkingPath);
        }

        /* Maybe an exact match on disk? */

        else if (PvfsSysStat(pszWorkingPath, &Stat) == STATUS_SUCCESS)
        {
            strncpy(pszResolvedPath, pszWorkingPath, PATH_MAX-1);
            Length = PATH_MAX - RtlCStringNumChars(pszResolvedPath);
            RtlCStringFree(&pszResWorkingPath);

            ntError = PvfsPathCacheAdd(pszResolvedPath);
            BAIL_ON_NT_STATUS(ntError);
        }

        /* Do the work ourselves */

        else
        {
            /* Enumerate directory entries and look for a match */

            ntError = PvfsSysOpenDir(pszResolvedPath, &pDir);
            if (ntError == STATUS_NOT_A_DIRECTORY)
            {
                ntError = STATUS_OBJECT_PATH_NOT_FOUND;
            }
            BAIL_ON_NT_STATUS(ntError);

            for(ntError = PvfsSysReadDir(pDir, &pDirEntry);
                pDirEntry;
                ntError = PvfsSysReadDir(pDir, &pDirEntry))
            {
                /* First check the error return */
                BAIL_ON_NT_STATUS(ntError);

                if (RtlCStringIsEqual(pszComponent, pDirEntry->d_name, FALSE)) {
                    break;
                }
            }

            /* Did we find a match? */

            if (!pDirEntry) {
                /* Return code depends on whether the last component was
                   not found or if an intermediate component was invalid */

                if (pszCursor == NULL)
                {
                    ntError = STATUS_OBJECT_NAME_NOT_FOUND;
                }
                else
                {
                    ntError = STATUS_OBJECT_PATH_NOT_FOUND;
                }

                BAIL_ON_NT_STATUS(ntError);
            }

            strncat(pszResolvedPath, "/", Length-1);
            Length -= 1;
            strncat(pszResolvedPath, pDirEntry->d_name, Length-1);
            Length -= RtlCStringNumChars(pDirEntry->d_name);

            ntError = PvfsSysCloseDir(pDir);
            pDir = NULL;
            BAIL_ON_NT_STATUS(ntError);

            ntError = PvfsPathCacheAdd(pszResolvedPath);
            BAIL_ON_NT_STATUS(ntError);

        }

        /* Cleanup for next loop */


        if (pszCursor) {
            *pszCursor = '/';
        }

        if ((pszComponent = strchr(pszComponent, '/')) != NULL) {
            pszComponent++;
        }
    }

    /* Did we finish? */

    if ((Length <= 0) && (pszComponent != NULL)) {
        ntError = STATUS_NAME_TOO_LONG;
        BAIL_ON_NT_STATUS(ntError);
    }

    *ppszResolvedPath = pszResolvedPath;
    pszResolvedPath = NULL;

    ntError = STATUS_SUCCESS;

cleanup:
    RtlCStringFree(&pszPath);
    RtlCStringFree(&pszWorkingPath);
    RtlCStringFree(&pszResWorkingPath);
    RtlCStringFree(&pszResolvedPath);

    if (pDir) {
        PvfsSysCloseDir(pDir);
    }

    return ntError;

error:
    goto cleanup;
}
Esempio n. 11
0
NTSTATUS
PvfsLookupPath(
    PSTR *ppszDiskPath,
    PCSTR pszPath,
    BOOLEAN bCaseSensitive
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PVFS_STAT Stat = {0};
    PSTR pszDiskPath = NULL;

    /* Check the cache */

    ntError = PvfsPathCacheLookup(&pszDiskPath, pszPath);
    if (ntError == STATUS_SUCCESS)
    {
        /* Check that the path is still good.  If not fallback
           to manual checks */

        ntError = PvfsSysStat(pszDiskPath, &Stat);
        if (ntError == STATUS_SUCCESS) {
            *ppszDiskPath = pszDiskPath;
            pszDiskPath = NULL;
            goto cleanup;
        }

        LwRtlCStringFree(&pszDiskPath);
        pszDiskPath = NULL;
    }

    /* See if we are lucky */

    ntError = PvfsSysStat(pszPath, &Stat);
    if (ntError == STATUS_SUCCESS)
    {
        ntError = RtlCStringDuplicate(ppszDiskPath, pszPath);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsPathCacheAdd(*ppszDiskPath);
        BAIL_ON_NT_STATUS(ntError);

        goto cleanup;
    }

    /* Done if use case sensitive matches */

    if (bCaseSensitive) {
        ntError = STATUS_OBJECT_NAME_NOT_FOUND;
        BAIL_ON_NT_STATUS(ntError);
    }

    /* Resolve the path */

    ntError = PvfsResolvePath(ppszDiskPath, pszPath);
    BAIL_ON_NT_STATUS(ntError);

    /* This should succeed now */
    ntError = PvfsSysStat(*ppszDiskPath, &Stat);
    BAIL_ON_NT_STATUS(ntError);

cleanup:
    LwRtlCStringFree(&pszDiskPath);

    return ntError;

error:
    LwRtlCStringFree(ppszDiskPath);

    goto cleanup;
}