Пример #1
0
NTSTATUS
SqliteCacheUpdateValuesInfo(
    DWORD dwOffSet,
    IN OUT PREG_KEY_CONTEXT pKeyResult,
    OUT size_t* psNumValues
    )
{
	NTSTATUS status = STATUS_SUCCESS;
    BOOLEAN bInLock = FALSE;

    BAIL_ON_NT_INVALID_POINTER(pKeyResult);

    LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pKeyResult->mutex);

    status = SqliteCacheUpdateValuesInfo_inlock(dwOffSet,
                                                pKeyResult,
                                                psNumValues);
    BAIL_ON_NT_STATUS(status);

cleanup:
    LWREG_UNLOCK_RWMUTEX(bInLock, &pKeyResult->mutex);

    return status;

error:
    goto cleanup;
}
Пример #2
0
// This can be called when a DB lock and active key list lock are both held
NTSTATUS
SqliteDeleteKeyInternal_inlock_inDblock(
	IN HANDLE handle,
    IN PCWSTR pwszKeyName
    )
{
	NTSTATUS status = STATUS_SUCCESS;
    PWSTR pwszParentKeyName = NULL;
    PREG_KEY_HANDLE pKeyHandle = NULL;
    // Do not free
    PREG_KEY_CONTEXT pKeyCtx = NULL;

    status = SqliteDeleteActiveKey_inlock((PCWSTR)pwszKeyName);
    BAIL_ON_NT_STATUS(status);

    status = SqliteOpenKeyInternal_inlock_inDblock(handle,
    		                                pwszKeyName,
    		                                0,
                                            &pKeyHandle);
    BAIL_ON_NT_STATUS(status);

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

    // Delete all the values of this key
    status = RegDbDeleteKey_inlock(ghCacheConnection, pKeyCtx->qwId, pKeyCtx->qwSdId, pwszKeyName);
    BAIL_ON_NT_STATUS(status);

    status = SqliteGetParentKeyName(pwszKeyName, '\\',&pwszParentKeyName);
    BAIL_ON_NT_STATUS(status);

    if (!LW_IS_NULL_OR_EMPTY_STR(pwszParentKeyName))
    {
        SqliteCacheResetParentKeySubKeyInfo_inlock(pwszParentKeyName);
    }

cleanup:
    SqliteSafeFreeKeyHandle_inlock(pKeyHandle);

    LWREG_SAFE_FREE_MEMORY(pwszParentKeyName);

    return status;

error:
    goto cleanup;
}
Пример #3
0
NTSTATUS
SqliteOpenKeyInternal(
	IN HANDLE handle,
    IN PCWSTR pwszFullKeyName, // Full Key Path
    IN ACCESS_MASK AccessDesired,
    OUT OPTIONAL PREG_KEY_HANDLE* ppKeyHandle
    )
{
	NTSTATUS status = STATUS_SUCCESS;
	PREG_SRV_API_STATE pServerState = (PREG_SRV_API_STATE)handle;
    BOOLEAN bInLock = FALSE;

    BAIL_ON_NT_INVALID_STRING(pwszFullKeyName);

    BAIL_ON_NT_INVALID_POINTER(handle);

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

    LWREG_LOCK_MUTEX(bInLock, &gActiveKeyList.mutex);

    // pServerState->pToken should be created at this point
    status = SqliteOpenKeyInternal_inlock(handle,
    		                              pwszFullKeyName,
    		                              AccessDesired,
    		                              ppKeyHandle);
    BAIL_ON_NT_STATUS(status);

cleanup:
    LWREG_UNLOCK_MUTEX(bInLock, &gActiveKeyList.mutex);

    return status;

error:
    goto cleanup;
}
Пример #4
0
NTSTATUS
SqliteCacheInsertDbKeyInfo_inlock(
    IN PREG_DB_KEY pRegKey
    )
{
	NTSTATUS status = STATUS_SUCCESS;

	BAIL_ON_NT_INVALID_POINTER(pRegKey);

    status = RegHashSetValue(gRegDbKeyList.pKeyList,
                             (PVOID)pRegKey->pwszFullKeyName,
                             (PVOID)pRegKey);
    BAIL_ON_NT_STATUS(status);

cleanup:

    return status;

error:
    goto cleanup;
}
Пример #5
0
NTSTATUS
SqliteCacheKeyDefaultValuesInfo(
    IN OUT PREG_KEY_CONTEXT pKeyResult
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    BOOLEAN bInLock = FALSE;

    BAIL_ON_NT_INVALID_POINTER(pKeyResult);

    LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pKeyResult->mutex);

    status = SqliteCacheKeyDefaultValuesInfo_inlock(pKeyResult);
    BAIL_ON_NT_STATUS(status);

cleanup:
    LWREG_UNLOCK_RWMUTEX(bInLock, &pKeyResult->mutex);

    return status;

error:
    goto cleanup;
}
Пример #6
0
NTSTATUS
RegHexStrToByteArray(
    IN PCSTR pszHexString,
    IN OPTIONAL DWORD* pdwHexStringLength,
    OUT UCHAR** ppucByteArray,
    OUT DWORD*  pdwByteArrayLength
    )
{
    NTSTATUS status = 0;
    DWORD i = 0;
    DWORD dwHexChars = 0;
    UCHAR* pucByteArray = NULL;
    DWORD dwByteArrayLength = 0;

    BAIL_ON_NT_INVALID_POINTER(pszHexString);

    if (pdwHexStringLength)
    {
        dwHexChars = *pdwHexStringLength;
    }
    else
    {
        dwHexChars = strlen(pszHexString);
    }
    dwByteArrayLength = dwHexChars / 2;

    if ((dwHexChars & 0x00000001) != 0)
    {
       status = STATUS_INVALID_PARAMETER;
       BAIL_ON_NT_STATUS(status);
    }

    status = LW_RTL_ALLOCATE((PVOID*)&pucByteArray, UCHAR,
            		          sizeof(*pucByteArray)* dwByteArrayLength);
    BAIL_ON_NT_STATUS(status);

    for (i = 0; i < dwByteArrayLength; i++)
    {
        CHAR hexHi = pszHexString[2*i];
        CHAR hexLow = pszHexString[2*i + 1];

        UCHAR ucHi = 0;
        UCHAR ucLow = 0;

        status = RegHexCharToByte(hexHi, &ucHi);
        BAIL_ON_NT_STATUS(status);

        status = RegHexCharToByte(hexLow, &ucLow);
        BAIL_ON_NT_STATUS(status);

        pucByteArray[i] = (ucHi * 16) + ucLow;
    }

    *ppucByteArray = pucByteArray;
    *pdwByteArrayLength = dwByteArrayLength;

cleanup:

    return status;

error:

    LWREG_SAFE_FREE_MEMORY(pucByteArray);
    *ppucByteArray = NULL;
    *pdwByteArrayLength = 0;

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

}
Пример #9
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;
}