/*
* Copyright Likewise Software 2004-2009
* All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the license, or (at
* your option) any later version.
*
* This library 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 Lesser
* General Public License for more details. You should have received a copy
* of the GNU Lesser 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
* LESSER 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:
*
* import.c
*
* Abstract:
*
* Registry
*
* Registry import utilities (import a win32 compatible registry file)
* Originally implemented for regimport (regimport.c)
*
* Authors: Wei Fu (wfu@likewise.com)
* Adam Bernstein (abernstein@likewise.com)
*
*/
#include "rsutils.h"
#include <../parse/includes.h>
#include
#include
static
DWORD
ProcessImportedKeyName(
HANDLE hReg,
PCSTR pszKeyName
)
{
DWORD dwError = 0;
PCSTR pszDelim = "\\";
PWSTR pSubKey = NULL;
HKEY pNewKey = NULL;
PSTR pszCurrKeyName = NULL;
PSTR pszPrevKeyName = NULL;
PSTR pszKeyToken = NULL;
PSTR pszStrTokSav = NULL;
HKEY hCurrKey = NULL;
PSTR pszKeyNameCopy = NULL;
dwError = RegCStringDuplicate(&pszKeyNameCopy, pszKeyName);
BAIL_ON_REG_ERROR(dwError);
pszKeyToken = strtok_r (pszKeyNameCopy, pszDelim, &pszStrTokSav);
if (!LW_IS_NULL_OR_EMPTY_STR(pszKeyToken))
{
if (!strcmp(pszKeyToken, HKEY_THIS_MACHINE))
{
dwError = RegOpenKeyExA(
hReg,
NULL,
HKEY_THIS_MACHINE,
0,
KEY_ALL_ACCESS,
&hCurrKey);
BAIL_ON_REG_ERROR(dwError);
}
else
{
REG_LOG_DEBUG("Found invalid Key Path in REG file that is imported");
goto cleanup;
}
}
pszKeyToken = strtok_r (NULL, pszDelim, &pszStrTokSav);
while (!LW_IS_NULL_OR_EMPTY_STR(pszKeyToken))
{
dwError = RegWC16StringAllocateFromCString(&pSubKey,
pszKeyToken);
BAIL_ON_REG_ERROR(dwError);
dwError = RegCreateKeyExW(
hReg,
hCurrKey,
pSubKey,
0,
NULL,
0,
KEY_ALL_ACCESS,
NULL,
&pNewKey,
NULL
);
if (LWREG_ERROR_KEYNAME_EXIST == dwError)
{
// Key has already been created (open it).
dwError = RegOpenKeyExW(hReg,
hCurrKey,
pSubKey,
0,
KEY_ALL_ACCESS,
&pNewKey);
BAIL_ON_REG_ERROR(dwError);
}
BAIL_ON_REG_ERROR(dwError);
LWREG_SAFE_FREE_MEMORY(pSubKey);
if (hCurrKey)
{
dwError = RegCloseKey(hReg, hCurrKey);
BAIL_ON_REG_ERROR(dwError);
hCurrKey = NULL;
}
hCurrKey = pNewKey;
pszKeyToken = strtok_r (NULL, pszDelim, &pszStrTokSav);
}
cleanup:
LWREG_SAFE_FREE_STRING(pszCurrKeyName);
LWREG_SAFE_FREE_STRING(pszPrevKeyName);
LWREG_SAFE_FREE_MEMORY(pSubKey);
LWREG_SAFE_FREE_STRING(pszKeyNameCopy);
if (pNewKey)
{
dwError = RegCloseKey(hReg,pNewKey);
}
if (hCurrKey)
{
dwError = RegCloseKey(hReg,hCurrKey);
}
return dwError;
error:
goto cleanup;
}
static
DWORD
ProcessImportedValue(
HANDLE hReg,
PREG_PARSE_ITEM pItem,
REGSHELL_UTIL_IMPORT_MODE eMode
)
{
DWORD dwError = 0;
CHAR c = '\\';
PCSTR pszDelim = "\\";
PSTR pszKeyToken = NULL;
PSTR pszStrTokSav = NULL;
//Do not free
PSTR pszSubKeyName = NULL;
PWSTR pSubKey = NULL;
//Do not close
HKEY hKey = NULL;
//Do not close
HKEY hCurrRootKey = NULL;
HKEY hRootKey = NULL;
HKEY hSubKey = NULL;
PSTR pszKeyName = NULL;
PBYTE pData = NULL;
DWORD cbData = 0;
DWORD dwDataType = 0;
BOOLEAN bSetValue = TRUE;
BAIL_ON_INVALID_HANDLE(hReg);
dwError = RegCStringDuplicate(&pszKeyName, (PCSTR)pItem->keyName);
BAIL_ON_REG_ERROR(dwError);
pszKeyToken = strtok_r (pszKeyName, pszDelim, &pszStrTokSav);
if (LW_IS_NULL_OR_EMPTY_STR(pszKeyToken))
{
pszKeyToken = pszKeyName;
}
if (!strcmp(pszKeyToken, HKEY_THIS_MACHINE))
{
if (!hRootKey)
{
dwError = RegOpenKeyExA(
hReg,
NULL,
HKEY_THIS_MACHINE,
0,
KEY_ALL_ACCESS,
&hRootKey);
BAIL_ON_REG_ERROR(dwError);
}
hCurrRootKey = hRootKey;
}
else
{
REG_LOG_DEBUG("Found invalid Key Path in REG file that is imported");
goto cleanup;
}
pszSubKeyName = strchr(pItem->keyName, c);
if (pszSubKeyName && !LW_IS_NULL_OR_EMPTY_STR(pszSubKeyName+1))
{
//Open the subkey
dwError = RegWC16StringAllocateFromCString(&pSubKey,
pszSubKeyName+1);
BAIL_ON_REG_ERROR(dwError);
dwError = RegOpenKeyExW(
hReg,
hCurrRootKey,
pSubKey,
0,
KEY_ALL_ACCESS,
&hSubKey);
BAIL_ON_REG_ERROR(dwError);
hKey = hSubKey;
}
else
{
hKey = hCurrRootKey;
}
cbData = pItem->type == REG_SZ ? pItem->valueLen+1 : pItem->valueLen;
dwError = RegAllocateMemory(sizeof(*pData) * cbData, (PVOID*)&pData);
BAIL_ON_REG_ERROR(dwError);
memcpy(pData, (PBYTE)pItem->value, cbData);
if (eMode == REGSHELL_UTIL_IMPORT_UPGRADE)
{
dwError = RegGetValueA(
hReg,
hKey,
NULL,
pItem->valueName,
0,
&dwDataType,
NULL,
NULL);
if (dwError == 0)
{
bSetValue = FALSE;
}
else
{
printf("[%s%s]\n",
HKEY_THIS_MACHINE,
pszSubKeyName ? pszSubKeyName : "");
printf(" '%s' Merged.\n", pItem->valueName);
}
}
if (bSetValue)
{
dwError = RegSetValueExA(
hReg,
hKey,
pItem->valueName,
0,
pItem->type,
pData,
cbData);
BAIL_ON_REG_ERROR(dwError);
}
cleanup:
LWREG_SAFE_FREE_MEMORY(pSubKey);
LWREG_SAFE_FREE_STRING(pszKeyName);
LWREG_SAFE_FREE_MEMORY(pData);
if (hSubKey)
{
dwError = RegCloseKey(hReg, hSubKey);
}
if (hRootKey)
{
dwError = RegCloseKey(hReg,hRootKey);
}
return dwError;
error:
goto cleanup;
}
DWORD
RegShellUtilImportCallback(
PREG_PARSE_ITEM pItem,
HANDLE hUserCtx
)
{
DWORD dwError = 0;
PREGSHELL_UTIL_IMPORT_CONTEXT pImportCtx =
(PREGSHELL_UTIL_IMPORT_CONTEXT ) hUserCtx;
if (pItem->type == REG_KEY)
{
dwError = ProcessImportedKeyName(
pImportCtx->hReg,
(PCSTR)pItem->keyName);
BAIL_ON_REG_ERROR(dwError);
}
else
{
dwError = ProcessImportedValue(
pImportCtx->hReg,
pItem,
pImportCtx->eImportMode);
BAIL_ON_REG_ERROR(dwError);
}
cleanup:
return dwError;
error:
goto cleanup;
}