/* Editor Settings: expandtabs and use 4 spaces for indentation
* ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
* -*- mode: c, c-basic-offset: 4 -*- */
/*
* Copyright Likewise Software 2004-2008
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. You should have received a copy of the GNU General
* Public License along with this program. If not, see
* .
*
* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
* GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
* license@likewisesoftware.com
*/
/*
* Copyright (C) Likewise Software. All rights reserved.
*
* Module Name:
*
* Abstract:
*
* Authors: Scott Salley
*
*/
#include "includes.h"
struct __LWIO_CONFIG_REG
{
HANDLE hConnection;
HKEY hKey;
PSTR pszConfigKey;
PSTR pszPolicyKey;
};
/**
* Read configuration values from the registry
*
* This function loops through a configuration table reading all given values
* from a registry key. If an entry is not found in the registry
* @dwConfigEntries determines whether an error is returned.
*
* @param[in] pszConfigKey Registry key path
* @param[in] pszPolicyKey Registry policy key path
* @param[in] pConfig Configuration table specifying parameter names
* @param[in] dwConfigEntries Number of table entries
* @param[in] bIgnoreNotFound Don't error if a parameter is not found in the
* registry.
*
* @return STATUS_SUCCESS, or appropriate error.
*/
NTSTATUS
LwIoProcessConfig(
PCSTR pszConfigKey,
PCSTR pszPolicyKey,
PLWIO_CONFIG_TABLE pConfig,
DWORD dwConfigEntries,
BOOLEAN bIgnoreNotFound
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
DWORD dwEntry = 0;
PLWIO_CONFIG_REG pReg = NULL;
ntStatus = LwIoOpenConfig(pszConfigKey, pszPolicyKey, &pReg);
BAIL_ON_NT_STATUS(ntStatus);
if (pReg == NULL)
{
goto error;
}
for (dwEntry = 0; dwEntry < dwConfigEntries; dwEntry++)
{
ntStatus = STATUS_SUCCESS;
switch (pConfig[dwEntry].Type)
{
case LwIoTypeString:
ntStatus = LwIoReadConfigString(
pReg,
pConfig[dwEntry].pszName,
pConfig[dwEntry].bUsePolicy,
pConfig[dwEntry].pValue);
break;
case LwIoTypeDword:
ntStatus = LwIoReadConfigDword(
pReg,
pConfig[dwEntry].pszName,
pConfig[dwEntry].bUsePolicy,
pConfig[dwEntry].dwMin,
pConfig[dwEntry].dwMax,
pConfig[dwEntry].pValue);
break;
case LwIoTypeBoolean:
ntStatus = LwIoReadConfigBoolean(
pReg,
pConfig[dwEntry].pszName,
pConfig[dwEntry].bUsePolicy,
pConfig[dwEntry].pValue);
break;
case LwIoTypeEnum:
ntStatus = LwIoReadConfigEnum(
pReg,
pConfig[dwEntry].pszName,
pConfig[dwEntry].bUsePolicy,
pConfig[dwEntry].dwMin,
pConfig[dwEntry].dwMax,
pConfig[dwEntry].ppszEnumNames,
pConfig[dwEntry].pValue);
break;
default:
break;
}
if (bIgnoreNotFound && ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
{
ntStatus = STATUS_SUCCESS;
}
BAIL_ON_NT_STATUS(ntStatus);
}
cleanup:
LwIoCloseConfig(pReg);
pReg = NULL;
return ntStatus;
error:
goto cleanup;
}
NTSTATUS
LwIoOpenConfig(
PCSTR pszConfigKey,
PCSTR pszPolicyKey,
PLWIO_CONFIG_REG *ppReg
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PLWIO_CONFIG_REG pReg = NULL;
ntStatus = LW_RTL_ALLOCATE(
(PVOID*)&pReg,
LWIO_CONFIG_REG,
sizeof(LWIO_CONFIG_REG));
BAIL_ON_NT_STATUS(ntStatus);
ntStatus = LwRtlCStringDuplicate(&pReg->pszConfigKey, pszConfigKey);
BAIL_ON_NT_STATUS(ntStatus);
ntStatus = LwRtlCStringDuplicate(&pReg->pszPolicyKey, pszPolicyKey);
BAIL_ON_NT_STATUS(ntStatus);
ntStatus = NtRegOpenServer(&pReg->hConnection);
if (ntStatus)
{
ntStatus = STATUS_SUCCESS;
goto error;
}
ntStatus = NtRegOpenKeyExA(
pReg->hConnection,
NULL,
HKEY_THIS_MACHINE,
0,
KEY_READ,
&(pReg->hKey));
if (ntStatus)
{
ntStatus = STATUS_SUCCESS;
goto error;
}
cleanup:
*ppReg = pReg;
return ntStatus;
error:
LwIoCloseConfig(pReg);
pReg = NULL;
goto cleanup;
}
VOID
LwIoCloseConfig(
PLWIO_CONFIG_REG pReg
)
{
if (pReg)
{
LwRtlCStringFree(&pReg->pszConfigKey);
LwRtlCStringFree(&pReg->pszPolicyKey);
if (pReg->hConnection)
{
if ( pReg->hKey )
{
NtRegCloseKey(pReg->hConnection, pReg->hKey);
pReg->hKey = NULL;
}
NtRegCloseServer(pReg->hConnection);
pReg->hConnection = NULL;
}
RTL_FREE(&pReg);
}
}
NTSTATUS
LwIoReadConfigString(
PLWIO_CONFIG_REG pReg,
PCSTR pszName,
BOOLEAN bUsePolicy,
PSTR *ppszValue
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
BOOLEAN bGotValue = FALSE;
char szValue[MAX_VALUE_LENGTH];
DWORD dwType = 0;
DWORD dwSize = 0;
if (bUsePolicy)
{
dwSize = sizeof(szValue);
memset(szValue, 0, dwSize);
ntStatus = NtRegGetValueA(
pReg->hConnection,
pReg->hKey,
pReg->pszPolicyKey,
pszName,
RRF_RT_REG_SZ,
&dwType,
szValue,
&dwSize);
if (!ntStatus)
{
bGotValue = TRUE;
}
}
if (!bGotValue)
{
dwSize = sizeof(szValue);
memset(szValue, 0, dwSize);
ntStatus = NtRegGetValueA(
pReg->hConnection,
pReg->hKey,
pReg->pszConfigKey,
pszName,
RRF_RT_REG_SZ,
&dwType,
szValue,
&dwSize);
if (!ntStatus)
{
bGotValue = TRUE;
}
}
if (bGotValue)
{
ntStatus = LwRtlCStringDuplicate(ppszValue, szValue);
BAIL_ON_NT_STATUS(ntStatus);
}
cleanup:
return ntStatus;
error:
goto cleanup;
}
NTSTATUS
LwIoReadConfigDword(
PLWIO_CONFIG_REG pReg,
PCSTR pszName,
BOOLEAN bUsePolicy,
DWORD dwMin,
DWORD dwMax,
PDWORD pdwValue
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
BOOLEAN bGotValue = FALSE;
DWORD dwValue = 0;
DWORD dwSize =0;
DWORD dwType = 0;
if (bUsePolicy)
{
dwSize = sizeof(dwValue);
ntStatus = NtRegGetValueA(
pReg->hConnection,
pReg->hKey,
pReg->pszPolicyKey,
pszName,
RRF_RT_REG_DWORD,
&dwType,
(PBYTE)&dwValue,
&dwSize);
if (!ntStatus)
{
bGotValue = TRUE;
}
}
if (!bGotValue)
{
dwSize = sizeof(dwValue);
ntStatus = NtRegGetValueA(
pReg->hConnection,
pReg->hKey,
pReg->pszConfigKey,
pszName,
RRF_RT_REG_DWORD,
&dwType,
(PBYTE)&dwValue,
&dwSize);
if (!ntStatus)
{
bGotValue = TRUE;
}
}
if (bGotValue)
{
if (dwMin <= dwValue && dwValue <= dwMax)
{
*pdwValue = dwValue;
}
else
{
ntStatus = STATUS_INVALID_PARAMETER;
}
}
return ntStatus;
}
NTSTATUS
LwIoReadConfigBoolean(
PLWIO_CONFIG_REG pReg,
PCSTR pszName,
BOOLEAN bUsePolicy,
PBOOLEAN pbValue
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
DWORD dwValue = *pbValue == TRUE ? 0x00000001 : 0x00000000;
ntStatus = LwIoReadConfigDword(
pReg,
pszName,
bUsePolicy,
0,
-1,
&dwValue);
BAIL_ON_LWIO_ERROR(ntStatus);
*pbValue = dwValue ? TRUE : FALSE;
cleanup:
return ntStatus;
error:
goto cleanup;
}
NTSTATUS
LwIoReadConfigEnum(
PLWIO_CONFIG_REG pReg,
PCSTR pszName,
BOOLEAN bUsePolicy,
DWORD dwMin,
DWORD dwMax,
const PCSTR *ppszEnumNames,
PDWORD pdwValue
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PSTR pszValue = NULL;
DWORD dwEnumIndex = 0;
ntStatus = LwIoReadConfigString(
pReg,
pszName,
bUsePolicy,
&pszValue);
BAIL_ON_NT_STATUS(ntStatus);
if (pszValue != NULL )
{
for (dwEnumIndex = 0;
dwEnumIndex <= dwMax - dwMin;
dwEnumIndex++)
{
if(LwRtlCStringCompare(
pszValue,
ppszEnumNames[dwEnumIndex], FALSE) == 0)
{
*pdwValue = dwEnumIndex + dwMin;
break;
}
}
}
cleanup:
LwRtlCStringFree(&pszValue);
return ntStatus;
error:
goto cleanup;
}
/*
local variables:
mode: c
c-basic-offset: 4
indent-tabs-mode: nil
tab-width: 4
end:
*/