Example #1
0
DWORD
VMCAAllocateStringW(
    PCWSTR pwszSrc,
    PWSTR* ppwszDst
    )
{
    DWORD dwError = 0;

    if (!pwszSrc || !ppwszDst)
    {
        dwError = ERROR_INVALID_PARAMETER;
    }
    else
    {
#ifdef _WIN32
        PWSTR pwszNewString = NULL;
        size_t len = wcslen(pwszSrc);
        dwError = VMCAAllocateMemory(
                        (DWORD) (len + 1)*sizeof(WCHAR), 
                        (PVOID *)&pwszNewString
                        );
        BAIL_ON_VMCA_ERROR(dwError);

        wcscpy_s(pwszNewString, (len + 1), pwszSrc);

        *ppwszDst = pwszNewString;
#else
		dwError = LwNtStatusToWin32Error(
						LwRtlWC16StringDuplicate(ppwszDst, pwszSrc));
        BAIL_ON_VMCA_ERROR(dwError);
#endif
    }
error:
    return dwError;
}
Example #2
0
NTSTATUS
RdrResolveToDomain(
    PCWSTR pwszHostname,
    PWSTR* ppwszDomain
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    BOOLEAN bLocked = FALSE;
    PWSTR pwszDomain = NULL;

    LWIO_LOCK_MUTEX(bLocked, &gRdrRuntime.Lock);

    if (!gRdrRuntime.pDomainHints)
    {
        status = STATUS_NOT_FOUND;
    }
    else
    {
        status = LwRtlHashMapFindKey(
            gRdrRuntime.pDomainHints,
            OUT_PPVOID(&pwszDomain),
            pwszHostname);
    }
    BAIL_ON_NT_STATUS(status);

    status = LwRtlWC16StringDuplicate(ppwszDomain, pwszDomain);
    BAIL_ON_NT_STATUS(status);

error:

    LWIO_UNLOCK_MUTEX(bLocked, &gRdrRuntime.Lock);

    return status;
}
Example #3
0
DWORD
RegWC16StringDuplicate(
    PWSTR* ppwszNewString,
    PCWSTR pwszOriginalString
    )
{
	return RegNtStatusToWin32Error(
	        LwRtlWC16StringDuplicate(ppwszNewString, pwszOriginalString)
	        );
}
Example #4
0
DWORD
IDMAllocateString(
    PWSTR  pszString,
    PWSTR* ppszString
    )
{
    DWORD  dwError = 0;
    PWSTR pszNewString = NULL;

    if (!pszString || !ppszString)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_ERROR(dwError);
    }
#ifdef _WIN32
{
    SIZE_T len = 0;
    len = wcslen(pszString);

    dwError = IDMAllocateMemory(
                    (len + 1) * sizeof(WCHAR),
                    (PVOID*)&pszNewString);
    BAIL_ON_ERROR(dwError);

    wcscpy_s(pszNewString, len+1, pszString);
}
#else

    dwError = LwRtlWC16StringDuplicate(
                  &pszNewString,
                  pszString);
    BAIL_ON_ERROR(dwError);

#endif

    *ppszString = pszNewString;

cleanup:

    return dwError;

error:

    if (ppszString)
    {
        *ppszString = NULL;
    }

    IDM_SAFE_FREE_MEMORY(pszNewString);

    goto cleanup;
}
Example #5
0
NTSTATUS
SqliteCreateKeyContext(
    IN PREG_DB_KEY pRegEntry,
    OUT PREG_KEY_CONTEXT* ppKeyResult
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PREG_KEY_CONTEXT pKeyResult = NULL;

    BAIL_ON_INVALID_REG_ENTRY(pRegEntry);

    status = LW_RTL_ALLOCATE((PVOID*)&pKeyResult, REG_KEY_CONTEXT, sizeof(*pKeyResult));
    BAIL_ON_NT_STATUS(status);

    pKeyResult->refCount = 1;

    pthread_rwlock_init(&pKeyResult->mutex, NULL);
    pKeyResult->pMutex = &pKeyResult->mutex;

    status = LwRtlWC16StringDuplicate(&pKeyResult->pwszKeyName, pRegEntry->pwszFullKeyName);
    BAIL_ON_NT_STATUS(status);

    status = SqliteGetParentKeyName(pKeyResult->pwszKeyName, (wchar16_t)'\\',&pKeyResult->pwszParentKeyName);
    BAIL_ON_NT_STATUS(status);

    pKeyResult->qwId = pRegEntry->version.qwDbId;

    pKeyResult->qwSdId = pRegEntry->qwAclIndex;

    // Cache ACL
    if (pRegEntry->ulSecDescLength)
    {
        status = LW_RTL_ALLOCATE((PVOID*)&pKeyResult->pSecurityDescriptor, VOID, pRegEntry->ulSecDescLength);
        BAIL_ON_NT_STATUS(status);

        memcpy(pKeyResult->pSecurityDescriptor, pRegEntry->pSecDescRel, pRegEntry->ulSecDescLength);
        pKeyResult->ulSecDescLength = pRegEntry->ulSecDescLength;
        pKeyResult->bHasSdInfo = TRUE;
    }

    *ppKeyResult = pKeyResult;

cleanup:
    return status;

error:
    RegSrvSafeFreeKeyContext(pKeyResult);
    *ppKeyResult = NULL;

    goto cleanup;
}
Example #6
0
static
NTSTATUS
RdrIsInPlaceRename(
    PRDR_CCB pFile,
    PFILE_RENAME_INFORMATION pRenameInfo,
    PBOOLEAN pbIsInPlace
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PWSTR pwszShare = NULL;
    PWSTR pwszFile = NULL;
    PWSTR pwszExisting = NULL;
    PWSTR pwszNew = NULL;

    status = RdrConvertPath(
        pRenameInfo->FileName,
        NULL,
        &pwszShare,
        &pwszFile
        );
    BAIL_ON_NT_STATUS(status);
    status = LwRtlWC16StringAllocatePrintfW(
        &pwszNew,
        L"%ws%ws",
        pwszShare,
        pwszFile);
    BAIL_ON_NT_STATUS(status);

    status = LwRtlWC16StringDuplicate(&pwszExisting, pFile->pwszCanonicalPath);
    BAIL_ON_NT_STATUS(status);

    RdrTrimLastPathElement(pwszNew);
    RdrTrimLastPathElement(pwszExisting);

    *pbIsInPlace = LwRtlWC16StringIsEqual(pwszNew, pwszExisting, FALSE);
cleanup:

    RTL_FREE(&pwszShare);
    RTL_FREE(&pwszFile);
    RTL_FREE(&pwszExisting);
    RTL_FREE(&pwszNew);

    return status;

error:

    *pbIsInPlace = FALSE;

    goto cleanup;
}
Example #7
0
NTSTATUS
RegWcStrDupOrNull(
    PCWSTR pwszInputString,
    PWSTR *ppwszOutputString
    )
{
    if (pwszInputString == NULL)
    {
        *ppwszOutputString = NULL;
        return STATUS_SUCCESS;
    }
    else
    {
        return LwRtlWC16StringDuplicate(ppwszOutputString, pwszInputString);
    }
}
Example #8
0
static NTSTATUS
_MemRegDuplicateWC16Array(
    IN PWSTR *ppwszArray,
    OUT PWSTR **pppwszCopyArray)
{
    NTSTATUS status = 0;
    PWSTR *ppwszRetStrings = NULL;
    PWSTR pwszRetString = NULL;
    DWORD index = 0;

    /* Count number of entries first */
    for (index=0; ppwszArray[index]; index++)
        ;
    index++;

    /* Allocate array of pointers to wide strings */
    status = LW_RTL_ALLOCATE(
                 (PVOID*) &ppwszRetStrings,
                 PWSTR,
                 sizeof(PWSTR) * index);
    BAIL_ON_NT_STATUS(status);
    memset(ppwszRetStrings, 0, sizeof(PWSTR) * index);

    /* Duplicate the strings */
     
    for (index=0; ppwszArray[index]; index++)
    {
        status = LwRtlWC16StringDuplicate(
                     &pwszRetString,
                     ppwszArray[index]); 
                     BAIL_ON_NT_STATUS(status);
        ppwszRetStrings[index] = pwszRetString;
        pwszRetString = NULL;
    }

    *pppwszCopyArray = ppwszRetStrings;
cleanup:
    return status;

error:
    LWREG_SAFE_FREE_MEMORY(ppwszRetStrings);
    LWREG_SAFE_FREE_MEMORY(pwszRetString);
    goto cleanup;
}
Example #9
0
ULONG
VmDirAllocateStringW(
    PCWSTR pwszSrc,
    PWSTR* ppwszDst
    )
{
    ULONG ulError = 0;

    if (!pwszSrc || !ppwszDst)
    {
        ulError = ERROR_INVALID_PARAMETER;
    }
    else
    {
        ulError = LwNtStatusToWin32Error(
                        LwRtlWC16StringDuplicate(ppwszDst, pwszSrc));
    }

    return ulError;
}
Example #10
0
NTSTATUS
MemRegStoreGetNodeValueAttributes(
    PMEMREG_VALUE hValue,
    OUT OPTIONAL PLWREG_CURRENT_VALUEINFO* ppCurrentValue,
    OUT OPTIONAL PLWREG_VALUE_ATTRIBUTES* ppValueAttributes)
{
    NTSTATUS status = 0;
    PWSTR *ppwszEnumStrings = NULL;
    PWSTR pwszEnumString = NULL;
    PWSTR pwszDocString = NULL;
    PLWREG_CURRENT_VALUEINFO pCurrentValue = NULL;
    PLWREG_VALUE_ATTRIBUTES pValueAttributes = NULL;
    PBYTE pRetCurrentValueData = NULL;
    PBYTE pRetAttributeValueData = NULL;
    DWORD dwValueLen = 0;
    BOOLEAN bHasAttributes = FALSE;

    dwValueLen = hValue->DataLen;
    if (ppCurrentValue)
    {
        if ((dwValueLen > 0 && hValue->Data &&
            hValue->Attributes.DefaultValueLen &&
            hValue->Attributes.pDefaultValue && 
            (dwValueLen != hValue->Attributes.DefaultValueLen ||
             memcmp(hValue->Data,
                    hValue->Attributes.pDefaultValue,
                    dwValueLen))) ||
             (dwValueLen > 0 && hValue->Data))
        {
            status = LW_RTL_ALLOCATE((PVOID*) &pCurrentValue,
                                     LWREG_CURRENT_VALUEINFO,
                                     sizeof(*pCurrentValue));
            BAIL_ON_NT_STATUS(status);


            status = LW_RTL_ALLOCATE((PVOID*) &pRetCurrentValueData,
                                     BYTE,
                                     dwValueLen);
            BAIL_ON_NT_STATUS(status);
            memset(pRetCurrentValueData, 0, dwValueLen);
            memcpy(pRetCurrentValueData, hValue->Data, dwValueLen);
        }
    }

    if (ppValueAttributes)
    {
        /* Always allocate a return attributes block */
        status = LW_RTL_ALLOCATE((PVOID*) &pValueAttributes,
                                 LWREG_VALUE_ATTRIBUTES,
                                 sizeof(*pValueAttributes));
        BAIL_ON_NT_STATUS(status);
        memset(pValueAttributes, 0, sizeof(*pValueAttributes));

        if (hValue->Attributes.DefaultValueLen > 0)
        {
            status = LW_RTL_ALLOCATE(
                         (PVOID*) &pRetAttributeValueData, 
                         BYTE, 
                         sizeof(BYTE) * hValue->Attributes.DefaultValueLen);
            BAIL_ON_NT_STATUS(status);
            memset(pRetAttributeValueData, 
                   0, 
                   sizeof(*pRetAttributeValueData) * 
                       hValue->Attributes.DefaultValueLen);
            memcpy(pRetAttributeValueData,
                   hValue->Attributes.pDefaultValue,
                   hValue->Attributes.DefaultValueLen);
            bHasAttributes = TRUE;
        }
    
        /*
         * Duplicate the documentation string, if present
         */
        if (hValue->Attributes.pwszDocString) { 
            status = LwRtlWC16StringDuplicate(&pwszDocString, 
                         hValue->Attributes.pwszDocString);
            BAIL_ON_NT_STATUS(status);
            bHasAttributes = TRUE;
        }

        if (hValue->Attributes.RangeType == LWREG_VALUE_RANGE_TYPE_ENUM &&
            hValue->Attributes.Range.ppwszRangeEnumStrings)
        {
            status = _MemRegDuplicateWC16Array(
                         hValue->Attributes.Range.ppwszRangeEnumStrings,
                         &ppwszEnumStrings);
            BAIL_ON_NT_STATUS(status);
            bHasAttributes = TRUE;
        }
    }

    if (!bHasAttributes && ppValueAttributes)
    {
        status = STATUS_OBJECT_NAME_NOT_FOUND;
        BAIL_ON_NT_STATUS(status);
    }

    /* Assign all allocated data to return optional return structures */
    if (pCurrentValue)
    {
         pCurrentValue->dwType = hValue->Type;
         pCurrentValue->pvData = pRetCurrentValueData;
         pCurrentValue->cbData = dwValueLen;
         *ppCurrentValue = pCurrentValue;
    }

    if (pValueAttributes)
    {
        *pValueAttributes = hValue->Attributes;
        /* 
         * The default type must always be returned by the
         * attributes structure. Seems like a bug with value
         * handling on the client-side.
         */
        if (hValue->Attributes.ValueType == 0)
        {
            pValueAttributes->ValueType = hValue->Type;
        }
        pValueAttributes->pDefaultValue = pRetAttributeValueData;
        pValueAttributes->pwszDocString = pwszDocString;
        if (ppwszEnumStrings)
        {
            pValueAttributes->Range.ppwszRangeEnumStrings = ppwszEnumStrings;
        }
        *ppValueAttributes = pValueAttributes;
    }

cleanup:
    return status;

error:
    /* Free a bunch of stuff here if something fails */

    LWREG_SAFE_FREE_MEMORY(pValueAttributes);
    LWREG_SAFE_FREE_MEMORY(pCurrentValue);
    LWREG_SAFE_FREE_MEMORY(pRetCurrentValueData);
    LWREG_SAFE_FREE_MEMORY(pRetAttributeValueData);
    LWREG_SAFE_FREE_MEMORY(pwszDocString);
    LWREG_SAFE_FREE_MEMORY(pwszEnumString);
    _MemDbFreeWC16Array(ppwszEnumStrings);
    goto cleanup;
}
Example #11
0
NTSTATUS
MemRegStoreAddNodeAttribute(
    PMEMREG_VALUE hValue,
    IN PLWREG_VALUE_ATTRIBUTES pAttributes)
{
    NTSTATUS status = 0;
    BYTE *pbData = NULL;
    PWSTR *ppwszEnumStrings = NULL;
    PWSTR pwszEnumString = NULL;
    PWSTR pwszDocString = NULL;

    /*
     * Assign all scaler types first. Then allocate data and duplicate
     * pointer types.
     */
    if (pAttributes->DefaultValueLen > 0)
    {
        status = LW_RTL_ALLOCATE(
                     (PVOID*) &pbData, 
                     BYTE, 
                     sizeof(*pbData) * pAttributes->DefaultValueLen);
        BAIL_ON_NT_STATUS(status);
        memset(pbData, 0, sizeof(*pbData) * pAttributes->DefaultValueLen);
        memcpy(pbData,
               pAttributes->pDefaultValue,
               pAttributes->DefaultValueLen);
    }

    /*
     * Duplicate the documentation string, if present
     */
    if (pAttributes->pwszDocString) { 
        status = LwRtlWC16StringDuplicate(&pwszDocString, 
                     pAttributes->pwszDocString);
        BAIL_ON_NT_STATUS(status);
    }

    /*
     * Duplicate the multi-string range array when
     * range type is RANGE_ENUM and the array is present.
     */
    if (pAttributes->RangeType == LWREG_VALUE_RANGE_TYPE_ENUM &&
        pAttributes->Range.ppwszRangeEnumStrings)
    {
        status = _MemRegDuplicateWC16Array(
                     pAttributes->Range.ppwszRangeEnumStrings,
                     &ppwszEnumStrings);
        BAIL_ON_NT_STATUS(status);
    }

    /*
     * Assign all allocated memory present in the attributes structure
     * to the value node.
     */
    if (pbData)
    {
        LWREG_SAFE_FREE_MEMORY(hValue->Attributes.pDefaultValue);
    }
    if (pwszDocString)
    {
         LWREG_SAFE_FREE_MEMORY(hValue->Attributes.pwszDocString);
    }

    hValue->Attributes = *pAttributes;
    if (pAttributes->DefaultValueLen > 0)
    {
        hValue->Attributes.pDefaultValue = (PVOID) pbData;
    }
    hValue->Attributes.pwszDocString = pwszDocString;

    if (pAttributes->RangeType == 
            LWREG_VALUE_RANGE_TYPE_ENUM)
    {
        hValue->Attributes.Range.ppwszRangeEnumStrings = ppwszEnumStrings;
    }

cleanup:
    return status;

error:
    /* Free a bunch of stuff here if something fails */
    LWREG_SAFE_FREE_MEMORY(pbData);
    LWREG_SAFE_FREE_MEMORY(pwszDocString);
    LWREG_SAFE_FREE_MEMORY(pwszEnumString);
    _MemDbFreeWC16Array(ppwszEnumStrings);
    goto cleanup;
}
Example #12
0
NTSTATUS
MemRegStoreAddNodeValue(
    PMEMREG_NODE hDbNode,
    IN OPTIONAL PCWSTR pValueName,
    IN DWORD dwReserved,
    IN DWORD dwType,
    IN const BYTE *pData,
    DWORD cbData)
{
    NTSTATUS status = 0;
    PMEMREG_VALUE pNodeValue = NULL;
    PWSTR pwszName = NULL;
    WCHAR pwszNull[2] = {0};
    BYTE *pbData = NULL;
    PMEMREG_VALUE *newValues;
    DWORD index = 0;

    status = LW_RTL_ALLOCATE(
                 (PVOID*) &pNodeValue, 
                 MEMREG_VALUE, 
                 sizeof(*pNodeValue));
    BAIL_ON_NT_STATUS(status);

    
    if (!pValueName || *pValueName == '\0')
    {
        pValueName = pwszNull;
    }
    status = LwRtlWC16StringDuplicate(&pwszName, pValueName);
    BAIL_ON_NT_STATUS(status);

    if (cbData > 0)
    {
        status = LW_RTL_ALLOCATE(
                     (PVOID*) &pbData, 
                     BYTE, 
                     sizeof(*pbData) * cbData);
        BAIL_ON_NT_STATUS(status);
        memset(pbData, 0, sizeof(*pbData) * cbData);
        if (pData)
        {
            memcpy(pbData, pData, cbData);
        }
    }

    status = NtRegReallocMemory(hDbNode->Values, 
                                (PVOID) &newValues,
                                (hDbNode->ValuesLen + 1) * sizeof(PMEMREG_VALUE));
    BAIL_ON_NT_STATUS(status);
    hDbNode->Values = newValues;

    pNodeValue->Name = pwszName;
    pNodeValue->Type = dwType;

    /* Clear out existing data before overwriting with new buffer */
    LWREG_SAFE_FREE_MEMORY(pNodeValue->Data);
    pNodeValue->Data = pbData;
    pNodeValue->DataLen = cbData;

    /* Insert new value in sorted order */
    if (hDbNode->ValuesLen > 0 && pValueName)
    {
        for (index=0;
             index<hDbNode->ValuesLen &&
             LwRtlWC16StringCompare(pValueName, hDbNode->Values[index]->Name)>0;
             index++)
        {
            ;
        }
        if (index < (hDbNode->ValuesLen+1))
        {
            memmove(&hDbNode->Values[index+1],
                    &hDbNode->Values[index],
                    sizeof(PMEMREG_NODE) * (hDbNode->ValuesLen - index));
            hDbNode->Values[index] = pNodeValue;
        }
        else
        {
            hDbNode->Values[hDbNode->ValuesLen] = pNodeValue;
        }
    }
    else
    {
        hDbNode->Values[hDbNode->ValuesLen] = pNodeValue;
    }

    hDbNode->ValuesLen++;

cleanup:
    return status;

error:
    LWREG_SAFE_FREE_MEMORY(pNodeValue);
    LWREG_SAFE_FREE_MEMORY(pwszName);
    LWREG_SAFE_FREE_MEMORY(pbData);
    LWREG_SAFE_FREE_MEMORY(newValues);
    goto cleanup;
}
Example #13
0
NTSTATUS
MemRegStoreAddNode(
    IN PMEMREG_NODE hParentNode,
    PCWSTR Name,
    DWORD NodeType,
    PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
    ULONG SecurityDescriptorLen,
    OUT PMEMREG_NODE *phRetParentNode,
    OUT OPTIONAL PMEMREG_NODE *ppRetNewNode)
{
    NTSTATUS status = 0;
    PMEMREG_NODE *pNodesArray = NULL;
    PMEMREG_NODE pNewNode = NULL;
    PWSTR newNodeName = NULL;
    DWORD index = 0;
    PMEMREG_NODE_SD pUpdatedNodeSd = NULL;

    if (hParentNode->SubNodeDepth == MEMREG_MAX_SUBNODES)
    {
        status = STATUS_TOO_MANY_NAMES;
        BAIL_ON_NT_STATUS(status);
    }
    status = NtRegReallocMemory(
                 hParentNode->SubNodes, 
                 (PVOID) &pNodesArray,
                 (hParentNode->NodesLen + 1) * sizeof(PMEMREG_NODE));
    BAIL_ON_NT_STATUS(status);

    status = LW_RTL_ALLOCATE(
                 (PVOID*) &pNewNode, PMEMREG_NODE, sizeof(MEMREG_NODE));
    BAIL_ON_NT_STATUS(status);
    memset(pNewNode, 0, sizeof(*pNewNode));

    status = LwRtlWC16StringDuplicate(&newNodeName, Name);
    BAIL_ON_NT_STATUS(status);
  
    pNodesArray[hParentNode->NodesLen] = NULL;
    hParentNode->SubNodes = pNodesArray;
    pNodesArray = NULL;

    if (NodeType > 1)
    {
        /*
         * Point new node to parent, if not root. Needed by some operations
         * that would manipulate parent structure (e.g. MemDeleteKey)
         */
        pNewNode->ParentNode = hParentNode;
    }

    /* Insert new node in sorted order */
    if (hParentNode->NodesLen > 0)
    {
        for (index=0; 
             index<hParentNode->NodesLen &&
             LwRtlWC16StringCompare(Name, hParentNode->SubNodes[index]->Name)>0;
             index++)
        {
            ;
        }
        if (index < (hParentNode->NodesLen+1))
        {
            memmove(&hParentNode->SubNodes[index+1],
                    &hParentNode->SubNodes[index],
                    sizeof(PMEMREG_NODE) * (hParentNode->NodesLen - index));
            hParentNode->SubNodes[index] = pNewNode;
        }
        else
        {
            hParentNode->SubNodes[hParentNode->NodesLen] = pNewNode;
        }
    }
    else
    {
        hParentNode->SubNodes[hParentNode->NodesLen] = pNewNode;
    }

    pNewNode->NodeType = NodeType;
    pNewNode->Name = newNodeName;
    newNodeName = NULL;

    status = MemRegStoreCreateSecurityDescriptor(
                 hParentNode->pNodeSd,
                 SecurityDescriptor,
                 SecurityDescriptorLen,
                 &pUpdatedNodeSd);
    BAIL_ON_NT_STATUS(status);
    if (pNewNode->pNodeSd)
    {
        LWREG_SAFE_FREE_MEMORY(pNewNode->pNodeSd->SecurityDescriptor);
    }
    LWREG_SAFE_FREE_MEMORY(pNewNode->pNodeSd);
    pNewNode->pNodeSd = pUpdatedNodeSd;

    hParentNode->NodesLen++;
    pNewNode->SubNodeDepth = hParentNode->SubNodeDepth+1;

    if (phRetParentNode)
    {
        *phRetParentNode = hParentNode;
    }
    if (ppRetNewNode)
    {
        *ppRetNewNode = pNewNode;
    }

cleanup:
    return status;

error:
    LWREG_SAFE_FREE_MEMORY(pNodesArray);
    LWREG_SAFE_FREE_MEMORY(pNewNode);
    LWREG_SAFE_FREE_MEMORY(newNodeName);
    goto cleanup;
}
Example #14
0
NTSTATUS
SqliteSetValueAttributes(
    IN HANDLE hRegConnection,
    IN HKEY hKey,
    IN OPTIONAL PCWSTR pwszSubKey,
    IN PCWSTR pValueName,
    IN PLWREG_VALUE_ATTRIBUTES pValueAttributes
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PWSTR pwszValueName = NULL;
    BOOLEAN bIsWrongType = TRUE;
    wchar16_t wszEmptyValueName[] = REG_EMPTY_VALUE_NAME_W;
    PWSTR pwszKeyNameWithSubKey = NULL;
    PREG_KEY_HANDLE pKeyHandle = (PREG_KEY_HANDLE)hKey;
    PREG_KEY_CONTEXT pKeyCtx = NULL;
    PREG_KEY_HANDLE pKeyHandleInUse = NULL;
    PREG_KEY_CONTEXT pKeyCtxInUse = NULL;
    // Do not free
    PBYTE pData = NULL;
    DWORD cbData = 0;

    BAIL_ON_NT_INVALID_POINTER(pKeyHandle);
    pKeyCtx = pKeyHandle->pKey;
    BAIL_ON_INVALID_KEY_CONTEXT(pKeyCtx);

    if (!RegValidValueAttributes(pValueAttributes))
    {
        status = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(status);
    }

    if (pwszSubKey)
    {
        status = LwRtlWC16StringAllocatePrintfW(
                        &pwszKeyNameWithSubKey,
                        L"%ws\\%ws",
                        pKeyCtx->pwszKeyName,
                        pwszSubKey);
        BAIL_ON_NT_STATUS(status);
    }

    status = SqliteOpenKeyInternal(hRegConnection,
                                   pwszSubKey ? pwszKeyNameWithSubKey : pKeyCtx->pwszKeyName,
                                   KEY_SET_VALUE,
                                   &pKeyHandleInUse);
    BAIL_ON_NT_STATUS(status);

    status = RegSrvAccessCheckKeyHandle(pKeyHandleInUse, KEY_SET_VALUE);
    BAIL_ON_NT_STATUS(status);

    pKeyCtxInUse = pKeyHandleInUse->pKey;
    BAIL_ON_INVALID_KEY_CONTEXT(pKeyCtxInUse);

    status = LwRtlWC16StringDuplicate(&pwszValueName, !pValueName ? wszEmptyValueName : pValueName);
    BAIL_ON_NT_STATUS(status);

    status = RegDbGetValueAttributes(
                              ghCacheConnection,
                              pKeyCtxInUse->qwId,
                              (PCWSTR)pwszValueName,
                              (REG_DATA_TYPE)pValueAttributes->ValueType,
                              &bIsWrongType,
                              NULL);
    if (!status)
    {
        status = STATUS_DUPLICATE_NAME;
        BAIL_ON_NT_STATUS(status);
    }
    else if (STATUS_OBJECT_NAME_NOT_FOUND == status)
    {
        status = 0;
    }
    BAIL_ON_NT_STATUS(status);

    pData = pValueAttributes->pDefaultValue;
    cbData = pValueAttributes->DefaultValueLen;

    if (cbData == 0)
    {
        goto done;
    }

    switch (pValueAttributes->ValueType)
    {
        case REG_BINARY:
        case REG_DWORD:
            break;

        case REG_MULTI_SZ:
        case REG_SZ:
            if (cbData == 1)
            {
                status = STATUS_INTERNAL_ERROR;
                BAIL_ON_NT_STATUS(status);
            }

            if (!pData || pData[cbData-1] != '\0' || pData[cbData-2] != '\0' )
            {
                status = STATUS_INVALID_PARAMETER;
                BAIL_ON_NT_STATUS(status);
            }

            break;

        default:
            status = STATUS_NOT_SUPPORTED;
            BAIL_ON_NT_STATUS(status);
    }

done:
    status = RegDbSetValueAttributes(ghCacheConnection,
                                     pKeyCtxInUse->qwId,
                                     pwszValueName,
                                     pValueAttributes);
    BAIL_ON_NT_STATUS(status);

    SqliteCacheResetKeyValueInfo(pKeyCtxInUse->pwszKeyName);

cleanup:

    LWREG_SAFE_FREE_MEMORY(pwszValueName);
    LWREG_SAFE_FREE_MEMORY(pwszKeyNameWithSubKey);
    SqliteSafeFreeKeyHandle(pKeyHandleInUse);

    return status;

error:
    goto cleanup;
}
Example #15
0
NTSTATUS
SqliteDeleteValueAttributes(
    IN HANDLE hRegConnection,
    IN HKEY hKey,
    IN OPTIONAL PCWSTR pwszSubKey,
    IN PCWSTR pValueName
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PWSTR pwszValueName = NULL;
    wchar16_t wszEmptyValueName[] = REG_EMPTY_VALUE_NAME_W;
    PWSTR pwszKeyNameWithSubKey = NULL;
    PREG_KEY_HANDLE pKeyHandle = (PREG_KEY_HANDLE)hKey;
    PREG_KEY_CONTEXT pKeyCtx = NULL;
    PREG_KEY_HANDLE pKeyHandleInUse = NULL;
    PREG_KEY_CONTEXT pKeyCtxInUse = NULL;


    BAIL_ON_NT_INVALID_POINTER(pKeyHandle);
    pKeyCtx = pKeyHandle->pKey;
    BAIL_ON_INVALID_KEY_CONTEXT(pKeyCtx);


    if (pwszSubKey)
    {
        status = LwRtlWC16StringAllocatePrintfW(
                        &pwszKeyNameWithSubKey,
                        L"%ws\\%ws",
                        pKeyCtx->pwszKeyName,
                        pwszSubKey);
        BAIL_ON_NT_STATUS(status);
    }

    status = SqliteOpenKeyInternal(hRegConnection,
                                   pwszSubKey ? pwszKeyNameWithSubKey : pKeyCtx->pwszKeyName,
                                   KEY_SET_VALUE | DELETE,
                                   &pKeyHandleInUse);
    BAIL_ON_NT_STATUS(status);

    status = RegSrvAccessCheckKeyHandle(pKeyHandleInUse, KEY_SET_VALUE);
    BAIL_ON_NT_STATUS(status);

    pKeyCtxInUse = pKeyHandleInUse->pKey;
    BAIL_ON_INVALID_KEY_CONTEXT(pKeyCtxInUse);

    status = LwRtlWC16StringDuplicate(&pwszValueName, !pValueName ? wszEmptyValueName : pValueName);
    BAIL_ON_NT_STATUS(status);

    status = RegDbGetValueAttributes(
                              ghCacheConnection,
                              pKeyCtxInUse->qwId,
                              (PCWSTR)pwszValueName,
                              REG_NONE,
                              NULL,
                              NULL);
    BAIL_ON_NT_STATUS(status);

    status = RegDbDeleteValueAttributes(ghCacheConnection,
                                        pKeyCtxInUse->qwId,
                                        (PCWSTR)pwszValueName);
    BAIL_ON_NT_STATUS(status);

    SqliteCacheResetKeyValueInfo(pKeyCtxInUse->pwszKeyName);

cleanup:
    SqliteSafeFreeKeyHandle(pKeyHandleInUse);
    LWREG_SAFE_FREE_MEMORY(pwszValueName);
    LWREG_SAFE_FREE_MEMORY(pwszKeyNameWithSubKey);

    return status;

error:
    goto cleanup;

}
Example #16
0
NTSTATUS
SqliteGetValueAttributes_Internal(
    IN HANDLE hRegConnection,
    IN HKEY hKey,
    IN OPTIONAL PCWSTR pwszSubKey,
    IN PCWSTR pValueName,
    IN OPTIONAL REG_DATA_TYPE dwType,
    // Whether bail or not in case there is no value attributes
    IN BOOLEAN bDoBail,
    OUT OPTIONAL PLWREG_CURRENT_VALUEINFO* ppCurrentValue,
    OUT OPTIONAL PLWREG_VALUE_ATTRIBUTES* ppValueAttributes
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PWSTR pwszValueName = NULL;
    PREG_DB_VALUE_ATTRIBUTES pRegEntry = NULL;
    PREG_DB_VALUE pRegValueEntry = NULL;
    BOOLEAN bIsWrongType = FALSE;
    wchar16_t wszEmptyValueName[] = REG_EMPTY_VALUE_NAME_W;
    PWSTR pwszKeyNameWithSubKey = NULL;
    PREG_KEY_HANDLE pKeyHandle = (PREG_KEY_HANDLE)hKey;
    PREG_KEY_CONTEXT pKeyCtx = NULL;
    PREG_KEY_HANDLE pKeyHandleInUse = NULL;
    PREG_KEY_CONTEXT pKeyCtxInUse = NULL;
    PLWREG_CURRENT_VALUEINFO pCurrentValue = NULL;
    BOOLEAN bInDbLock = FALSE;
    BOOLEAN bInLock = FALSE;
    PSTR pszError = NULL;
    PREG_DB_CONNECTION pConn = (PREG_DB_CONNECTION)ghCacheConnection;
    PREG_SRV_API_STATE pServerState = (PREG_SRV_API_STATE)hRegConnection;

    BAIL_ON_NT_INVALID_POINTER(pKeyHandle);
    pKeyCtx = pKeyHandle->pKey;
    BAIL_ON_INVALID_KEY_CONTEXT(pKeyCtx);

    if (!ppCurrentValue && !ppValueAttributes)
    {
        status = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(status);
    }

    if (pwszSubKey)
    {
        status = LwRtlWC16StringAllocatePrintfW(
                        &pwszKeyNameWithSubKey,
                        L"%ws\\%ws",
                        pKeyCtx->pwszKeyName,
                        pwszSubKey);
        BAIL_ON_NT_STATUS(status);
    }

    if (!pServerState->pToken)
    {
        status = RegSrvCreateAccessToken(pServerState->peerUID,
                                         pServerState->peerGID,
                                         &pServerState->pToken);
        BAIL_ON_NT_STATUS(status);
    }

    LWREG_LOCK_MUTEX(bInLock, &gActiveKeyList.mutex);

    ENTER_SQLITE_LOCK(&pConn->lock, bInDbLock);

    status = sqlite3_exec(
                    pConn->pDb,
                    "begin;",
                    NULL,
                    NULL,
                    &pszError);
    BAIL_ON_SQLITE3_ERROR(status, pszError);

    // pServerState->pToken should be created at this point
    status = SqliteOpenKeyInternal_inlock_inDblock(
                              hRegConnection,
                              pwszSubKey ? pwszKeyNameWithSubKey : pKeyCtx->pwszKeyName,
                              KEY_QUERY_VALUE,
                              &pKeyHandleInUse);
    BAIL_ON_NT_STATUS(status);

    // ACL check
    status = RegSrvAccessCheckKeyHandle(pKeyHandleInUse, KEY_QUERY_VALUE);
    BAIL_ON_NT_STATUS(status);

    pKeyCtxInUse = pKeyHandleInUse->pKey;
    BAIL_ON_INVALID_KEY_CONTEXT(pKeyCtxInUse);

    status = LwRtlWC16StringDuplicate(&pwszValueName, !pValueName ? wszEmptyValueName : pValueName);
    BAIL_ON_NT_STATUS(status);

    // Optionally get value
    if (ppCurrentValue)
    {
        status = RegDbGetKeyValue_inlock(
                                  ghCacheConnection,
                                  pKeyCtxInUse->qwId,
                                  pwszValueName,
                                  dwType,
                                  &bIsWrongType,
                                  &pRegValueEntry);
        if (!status)
        {
            status = LW_RTL_ALLOCATE((PVOID*)&pCurrentValue,
                                      LWREG_CURRENT_VALUEINFO,
                                      sizeof(*pCurrentValue));
            BAIL_ON_NT_STATUS(status);

            pCurrentValue->cbData = pRegValueEntry->dwValueLen;
            pCurrentValue->dwType = pRegValueEntry->type;

            if (pCurrentValue->cbData)
            {
                status = LW_RTL_ALLOCATE((PVOID*)&pCurrentValue->pvData,
                                         VOID,
                                         pCurrentValue->cbData);
                BAIL_ON_NT_STATUS(status);

                memcpy(pCurrentValue->pvData, pRegValueEntry->pValue, pCurrentValue->cbData);
            }
        }
        else if (LW_STATUS_OBJECT_NAME_NOT_FOUND ==  status)
        {
            status = 0;
        }
        BAIL_ON_NT_STATUS(status);
    }

    // Get value attributes
    if (ppValueAttributes)
    {
        status = RegDbGetValueAttributes_inlock(
                                         ghCacheConnection,
                                         pKeyCtxInUse->qwId,
                                         pwszValueName,
                                         REG_NONE,
                                         &bIsWrongType,
                                         &pRegEntry);
        if (!bDoBail && LW_STATUS_OBJECT_NAME_NOT_FOUND == status)
        {
            status = LW_RTL_ALLOCATE((PVOID*)&pRegEntry,
                                     REG_DB_VALUE_ATTRIBUTES,
                                     sizeof(*pRegEntry));
            BAIL_ON_NT_STATUS(status);
        }
        BAIL_ON_NT_STATUS(status);
    }

    status = sqlite3_exec(
                    pConn->pDb,
                    "end",
                    NULL,
                    NULL,
                    &pszError);
    BAIL_ON_SQLITE3_ERROR(status, pszError);

    REG_LOG_VERBOSE("Registry::sqldb.c SqliteGetValueAttributes_Internal() finished");

    if (ppCurrentValue)
    {
        *ppCurrentValue = pCurrentValue;
        pCurrentValue = NULL;
    }

    if (ppValueAttributes)
    {
        *ppValueAttributes = pRegEntry->pValueAttributes;
        pRegEntry->pValueAttributes = NULL;
    }

cleanup:

    LEAVE_SQLITE_LOCK(&pConn->lock, bInDbLock);

    LWREG_UNLOCK_MUTEX(bInLock, &gActiveKeyList.mutex);

    SqliteSafeFreeKeyHandle(pKeyHandleInUse);
    LWREG_SAFE_FREE_MEMORY(pwszValueName);
    LWREG_SAFE_FREE_MEMORY(pwszKeyNameWithSubKey);
    RegDbSafeFreeEntryValue(&pRegValueEntry);

    RegSafeFreeCurrentValueInfo(&pCurrentValue);
    RegDbSafeFreeEntryValueAttributes(&pRegEntry);

    return status;

error:
    if (pszError)
    {
        sqlite3_free(pszError);
    }
    sqlite3_exec(pConn->pDb,
                 "rollback",
                 NULL,
                 NULL,
                 NULL);

    if (ppCurrentValue)
    {
        *ppCurrentValue = NULL;
    }

    if (ppValueAttributes)
    {
        *ppValueAttributes  = NULL;
    }

    goto cleanup;
}
Example #17
0
NTSTATUS
RdrTreeConnect(
    PCWSTR pwszHostname,
    PCWSTR pwszSharename,
    PIO_CREDS pCreds,
    uid_t Uid,
    BOOLEAN bStopOnDfs,
    PRDR_OP_CONTEXT pContinue
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PRDR_OP_CONTEXT pContext = NULL;
    BOOLEAN bSocketLocked = FALSE;
    PRDR_SOCKET pSocket = NULL;

    status = RdrCreateContext(pContinue->pIrp, &pContext);
    BAIL_ON_NT_STATUS(status);

    LWIO_LOG_DEBUG("Tree connect context %p will continue %p\n", pContext, pContinue);

    pContext->State.TreeConnect.Uid = Uid;
    pContext->State.TreeConnect.bStopOnDfs = bStopOnDfs;
    pContext->State.TreeConnect.pContinue = pContinue;

    status = LwRtlWC16StringDuplicate(
        &pContext->State.TreeConnect.pwszSharename,
        pwszSharename);
    BAIL_ON_NT_STATUS(status);

    pContext->State.TreeConnect.pCreds = pCreds;

    status = RdrSocketFindOrCreate(
        pwszHostname,
        &pSocket);
    BAIL_ON_NT_STATUS(status);

    pContext->State.TreeConnect.pSocket = pSocket;

    LWIO_LOCK_MUTEX(bSocketLocked, &pSocket->mutex);

    switch (pSocket->state)
    {
    case RDR_SOCKET_STATE_NOT_READY:
        pSocket->state = RDR_SOCKET_STATE_CONNECTING;
        LWIO_UNLOCK_MUTEX(bSocketLocked, &pSocket->mutex);

        /* Add extra reference to socket for work item */
        RdrSocketRetain(pSocket);
        status = LwRtlQueueWorkItem(
            gRdrRuntime.pThreadPool,
            RdrSocketConnectWorkItem,
            pSocket,
            0);
        if (status)
        {
            /* Nevermind */
            RdrSocketRelease(pSocket);
        }
        BAIL_ON_NT_STATUS(status);

        pContext->Continue = RdrProcessNegotiateResponse;

        status = RdrTransceiveNegotiate(pContext, pSocket);
        BAIL_ON_NT_STATUS(status);
        break;
    case RDR_SOCKET_STATE_CONNECTING:
    case RDR_SOCKET_STATE_NEGOTIATING:
        pContext->Continue = RdrNegotiateComplete;
        LwListInsertTail(&pSocket->StateWaiters, &pContext->Link);
        status = STATUS_PENDING;
        BAIL_ON_NT_STATUS(status);
        break;
    case RDR_SOCKET_STATE_READY:
        LWIO_UNLOCK_MUTEX(bSocketLocked, &pSocket->mutex);
        RdrNegotiateComplete(pContext, STATUS_SUCCESS, pSocket);
        status = STATUS_PENDING;
        BAIL_ON_NT_STATUS(status);
        break;
    case RDR_SOCKET_STATE_ERROR:
        status = pSocket->error;
        BAIL_ON_NT_STATUS(status);
        break;
    }

cleanup:

    LWIO_UNLOCK_MUTEX(bSocketLocked, &pSocket->mutex);

    if (status != STATUS_PENDING)
    {
        RdrFreeTreeConnectContext(pContext);
    }

    return status;

error:

    if (status != STATUS_PENDING && pSocket)
    {
        LWIO_UNLOCK_MUTEX(bSocketLocked, &pSocket->mutex);
        RdrSocketInvalidate(pSocket, status);
        RdrSocketRelease(pSocket);
    }

    goto cleanup;
}
Example #18
0
NTSTATUS
MemRegStoreFindNodeSubkey(
    IN PMEMREG_NODE hDbNode,
    IN PCWSTR pwszSubKeyPath,
    OUT PMEMREG_NODE * phNode)
{
    NTSTATUS status = 0;
    PWSTR pwszTmpFullPath = NULL;
    PWSTR pwszSubKey = NULL;
    PWSTR pwszPtr = NULL;
    PMEMREG_NODE hParentKey = NULL;
    PMEMREG_NODE hSubKey = NULL;
    BOOLEAN bEndOfString = FALSE;


    BAIL_ON_NT_STATUS(status);

    if (!pwszSubKeyPath)
    {
        pwszSubKeyPath = (PCWSTR) L"";
    }


    status = LwRtlWC16StringDuplicate(&pwszTmpFullPath, pwszSubKeyPath);
    BAIL_ON_NT_STATUS(status);

    hParentKey = hDbNode;
    pwszSubKey = pwszTmpFullPath;
    do
    {
        pwszPtr = pwstr_wcschr(pwszSubKey, L'\\');
        if (pwszPtr)
        {
            *pwszPtr++ = L'\0';
        }
        else
        {
            pwszPtr = pwszSubKey;
            bEndOfString = TRUE;
        }

        /*
         * Iterate over subkeys in \ sepearated path.
         */
        status = MemRegStoreFindNode(
                     hParentKey,
                     pwszSubKey,
                     &hSubKey);
        hParentKey = hSubKey;
        pwszSubKey = pwszPtr;
    } while (status == 0 && !bEndOfString);
    if (status == 0)
    {
        *phNode = hParentKey;
    }

cleanup:
    LWREG_SAFE_FREE_MEMORY(pwszTmpFullPath);
    return status;
error:
    goto cleanup;
}
Example #19
0
BOOLEAN
RdrCreateTreeConnect2Complete(
    PRDR_OP_CONTEXT pContext,
    NTSTATUS status,
    PVOID pParam
    )
{
    PRDR_TREE2 pTree = pParam;
    PIRP pIrp = pContext->pIrp;
    ACCESS_MASK DesiredAccess = pIrp->Args.Create.DesiredAccess;
    LONG64 AllocationSize = pIrp->Args.Create.AllocationSize;
    FILE_SHARE_FLAGS ShareAccess = pIrp->Args.Create.ShareAccess;
    FILE_CREATE_DISPOSITION CreateDisposition = pIrp->Args.Create.CreateDisposition;
    FILE_CREATE_OPTIONS CreateOptions = pIrp->Args.Create.CreateOptions;
    FILE_ATTRIBUTES FileAttributes =  pIrp->Args.Create.FileAttributes;
    PIO_CREDS pCreds = IoSecurityGetCredentials(pIrp->Args.Create.SecurityContext);
    PIO_SECURITY_CONTEXT_PROCESS_INFORMATION pProcessInfo =
        IoSecurityGetProcessInfo(pIrp->Args.Create.SecurityContext);
    PRDR_CCB2 pFile = NULL;

    BAIL_ON_NT_STATUS(status);

    status = LwIoAllocateMemory(
        sizeof(RDR_CCB2),
        (PVOID*)&pFile);
    BAIL_ON_NT_STATUS(status);

    status = LwErrnoToNtStatus(pthread_mutex_init(&pFile->mutex, NULL));
    BAIL_ON_NT_STATUS(status);

    pFile->bMutexInitialized = TRUE;
    pFile->version = SMB_PROTOCOL_VERSION_2;
    pFile->pTree = pTree;
    pTree = NULL;

    status = LwRtlWC16StringDuplicate(&pFile->pwszPath, pContext->State.Create.pwszFilename);
    BAIL_ON_NT_STATUS(status);

    status = LwRtlWC16StringDuplicate(&pFile->pwszCanonicalPath, pContext->State.Create.pwszCanonicalPath);
    BAIL_ON_NT_STATUS(status);

    pContext->Continue = RdrFinishCreate2;

    pContext->State.Create.pFile2 = pFile;

    status = RdrTransceiveCreate2(
        pContext,
        pFile,
        DesiredAccess,
        AllocationSize,
        FileAttributes,
        ShareAccess,
        CreateDisposition,
        CreateOptions);
    switch (status)
    {
    case STATUS_SUCCESS:
    case STATUS_PENDING:
        break;
    default:
        pContext->Continue = RdrCreateTreeConnectComplete;
        pContext->State.Create.pFile2 = NULL;

        status = RdrDfsConnect(
            pFile->pTree->pSession->pSocket,
            pIrp->Args.Create.FileName.FileName,
            pCreds,
            pProcessInfo->Uid,
            status,
            &pContext->usTry,
            &pContext->State.Create.pwszFilename,
            &pContext->State.Create.pwszCanonicalPath,
            pContext);

        RdrReleaseFile2(pFile);
        pFile = NULL;

    }
    BAIL_ON_NT_STATUS(status);

cleanup:

    RTL_FREE(&pContext->State.Create.pwszFilename);
    RTL_FREE(&pContext->State.Create.pwszCanonicalPath);

    if (status != STATUS_PENDING)
    {
        RdrFreeContext(pContext);
        pIrp->IoStatusBlock.Status = status;
        IoIrpComplete(pIrp);
    }

    return FALSE;

error:

    if (status != STATUS_PENDING && pFile)
    {
        RdrReleaseFile2(pFile);
    }

    if (status != STATUS_PENDING && pTree)
    {
        RdrTree2Release(pTree);
    }

    goto cleanup;
}
Example #20
0
NTSTATUS
IoRtlPathUncToInternal(
    PCWSTR pwszUncPath,
    PWSTR* ppwszInternalPath
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PWSTR pwszCopy = NULL;
    PWSTR pwszIn = NULL;
    PWSTR pwszOut = NULL;
    CHAR szCwd[PATH_MAX];

    status = LwRtlWC16StringDuplicate(&pwszCopy, pwszUncPath);
    BAIL_ON_NT_STATUS(status);

    for(pwszIn = pwszOut = pwszCopy; *pwszIn; pwszIn++)
    {
        if (IoRtlPathIsSeparator(*pwszIn))
        {
            *(pwszOut++) = '/';
            while (IoRtlPathIsSeparator(pwszIn[1]))
            {
                pwszIn++;
            }
        }
        else
        {
            *(pwszOut++) = *pwszIn;
        }
    }

    *pwszOut = '\0';

    if (IoRtlPathIsSeparator(pwszUncPath[0]) && IoRtlPathIsSeparator(pwszUncPath[1]))
    {
        status = LwRtlWC16StringAllocatePrintfW(ppwszInternalPath, L"/rdr%ws", pwszCopy);
        BAIL_ON_NT_STATUS(status);
    }
    else if (IoRtlPathIsSeparator(pwszUncPath[0]))
    {
        status = LwRtlWC16StringAllocatePrintfW(ppwszInternalPath, L"/pvfs%ws", pwszCopy);
        BAIL_ON_NT_STATUS(status);
    }
    else
    {
        if (getcwd(szCwd, sizeof(szCwd)) == NULL)
        {
            status = STATUS_UNSUCCESSFUL;
            BAIL_ON_NT_STATUS(status);
        }

        status = LwRtlWC16StringAllocatePrintfW(ppwszInternalPath, L"/pvfs%s/%ws", szCwd, pwszCopy);
        BAIL_ON_NT_STATUS(status);
    }

cleanup:

    RTL_FREE(&pwszCopy);

    return status;

error:

    *ppwszInternalPath = NULL;

    goto cleanup;
}