diff options
Diffstat (limited to 'setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx')
-rw-r--r-- | setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx | 619 |
1 files changed, 619 insertions, 0 deletions
diff --git a/setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx b/setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx new file mode 100644 index 000000000000..361672790630 --- /dev/null +++ b/setup_native/source/win32/customactions/reg4msdoc/registrywnt.cxx @@ -0,0 +1,619 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +//--------------------------------------- +// +//--------------------------------------- + +#ifdef _MSC_VER +#pragma warning(push, 1) /* disable warnings within system headers */ +#endif +#include <windows.h> +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include <malloc.h> +#include "registrywnt.hxx" +#include "registryvalueimpl.hxx" +#include "registryexception.hxx" + +#include <assert.h> + +#ifdef _MSC_VER +#pragma warning(disable : 4786 4350) +#endif + +//--------------------------------------- +// +//--------------------------------------- + +const size_t MAX_TMP_BUFF_SIZE = 1024 * sizeof(wchar_t); + + +//############################################ +// Creation +// only possible through WindowsRegistry class +//############################################ + + +//----------------------------------------------------- +/** Create instance and open the specified Registry key +*/ +RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey, const std::wstring& KeyName) : + RegistryKeyImpl(RootKey, KeyName) +{ +} + +//----------------------------------------------------- +/** Create instance and open the specified Registry key +*/ +RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey) : + RegistryKeyImpl(RootKey) +{ +} + +//----------------------------------------------------- +/** Create an instances of the specified Registry key, + the key is assumed to be already opened. +*/ +RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable) : + RegistryKeyImpl(RootKey, SubKey, KeyName, Writeable) +{ +} + + +//############################################ +// Queries +//############################################ + + +//----------------------------------------------------- +/** The number of sub values of the key at hand + + @precond IsOpen = true + + @throws +*/ +size_t RegistryKeyImplWinNT::GetSubValueCount() const +{ + assert(IsOpen()); + + DWORD nSubValues = 0; + + LONG rc = RegQueryInfoKeyW( + m_hSubKey, + 0, 0, 0, 0, 0, 0, &nSubValues, 0, 0, 0, 0); + + if (ERROR_INVALID_HANDLE == rc) + throw RegistryIOException(rc); + else if (ERROR_SUCCESS != rc) + throw RegistryException(rc); + + return nSubValues; +} + +//----------------------------------------------------- +/** The number of sub-keys of the key at hand + + @precond IsOpen = true + + @throws +*/ +size_t RegistryKeyImplWinNT::GetSubKeyCount() const +{ + assert(IsOpen()); + + DWORD nSubKeys = 0; + + LONG rc = RegQueryInfoKeyA( + m_hSubKey, + 0, 0, 0, &nSubKeys, 0, 0, 0, 0, 0, 0, 0); + + if (ERROR_INVALID_HANDLE == rc) + throw RegistryIOException(rc); + else if (ERROR_SUCCESS != rc) + throw RegistryException(rc); + + return nSubKeys; +} + +//----------------------------------------------------- +/** +*/ +StringListPtr RegistryKeyImplWinNT::GetSubKeyNames() const +{ + assert(IsOpen()); + + wchar_t buff[1024]; + DWORD buff_size = sizeof(buff); + FILETIME ftime; + + StringList* key_names = new StringList(); + + LONG rc = ERROR_SUCCESS; + + for (DWORD i = 0; /* left empty */; i++) + { + rc = RegEnumKeyExW( + m_hSubKey, i, buff, &buff_size, + 0, 0, 0, &ftime); + + if (ERROR_SUCCESS != rc && + ERROR_MORE_DATA != rc) + break; + + buff_size = sizeof(buff); + + key_names->push_back(buff); + } + + if (ERROR_INVALID_HANDLE == rc) + throw RegistryIOException(rc); + else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc) + throw RegistryException(rc); + +#if (_MSC_VER < 1300) && !defined(__MINGW32__) + return key_names; +#else + return (StringListPtr) key_names; +#endif +} + +//----------------------------------------------------- +/** +*/ +StringListPtr RegistryKeyImplWinNT::GetSubValueNames() const +{ + assert(IsOpen()); + + wchar_t buff[1024]; + DWORD buff_size = sizeof(buff); + + StringList* value_names = new StringList(); + + LONG rc = ERROR_SUCCESS; + + for (DWORD i = 0; /* left empty */; i++) + { + rc = RegEnumValueW( + m_hSubKey, i, buff, &buff_size, + 0, 0, 0, 0); + + if (ERROR_SUCCESS != rc && + ERROR_MORE_DATA != rc) + break; + + buff_size = sizeof(buff); + + value_names->push_back(buff); + } + + if (ERROR_INVALID_HANDLE == rc) + throw RegistryIOException(rc); + else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc) + throw RegistryException(rc); + +#if (_MSC_VER < 1300) && !defined(__MINGW32__) + return value_names; +#else + return (StringListPtr) value_names; +#endif +} + +//----------------------------------------------------- +/** Get the specified registry value + + @precond IsOpen = true +*/ +RegistryValue RegistryKeyImplWinNT::GetValue(const std::wstring& Name) const +{ + assert(IsOpen()); + + DWORD Type; + wchar_t buff[MAX_TMP_BUFF_SIZE]; + DWORD size = sizeof(buff); + + LONG rc = RegQueryValueExW( + m_hSubKey, + Name.c_str(), + 0, + &Type, + reinterpret_cast<LPBYTE>(buff), + &size); + + if (ERROR_FILE_NOT_FOUND == rc) + throw RegistryValueNotFoundException(rc); + else if (ERROR_ACCESS_DENIED == rc) + throw RegistryAccessDeniedException(rc); + else if (ERROR_SUCCESS != rc) + throw RegistryException(rc); + + RegistryValue regval; + + if (REG_DWORD == Type) + { + regval = RegistryValue(new RegistryValueImpl(Name, *(reinterpret_cast<int*>(buff)))); + } + else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type) + { + if (size > 0) + regval = RegistryValue(new RegistryValueImpl(Name, std::wstring(reinterpret_cast<wchar_t*>(buff)))); + else + regval = RegistryValue(new RegistryValueImpl(Name, std::wstring())); + } + else + { + assert(false); + } + + return regval; +} + +//----------------------------------------------------- +/** Get the specified registry value, return the given + default value if value not found + + @precond IsOpen = true +*/ +RegistryValue RegistryKeyImplWinNT::GetValue(const std::wstring& Name, const RegistryValue& Default) const +{ + assert(IsOpen()); + + DWORD Type; + wchar_t buff[MAX_TMP_BUFF_SIZE]; + DWORD size = sizeof(buff); + + LONG rc = RegQueryValueExW( + m_hSubKey, + Name.c_str(), + 0, + &Type, + reinterpret_cast<LPBYTE>(buff), + &size); + + if (ERROR_FILE_NOT_FOUND == rc) + { + #if (_MSC_VER < 1300) && !defined(__MINGW32__) + return Default; + #else + RegistryValue regval_ptr; + regval_ptr = RegistryValue(new RegistryValueImpl(*Default)); + return regval_ptr; + #endif + } + + if (ERROR_ACCESS_DENIED == rc) + throw RegistryAccessDeniedException(rc); + else if (ERROR_SUCCESS != rc) + throw RegistryException(rc); + + RegistryValue regval; + + if (REG_DWORD == Type) + regval = RegistryValue(new RegistryValueImpl(Name, *reinterpret_cast<int*>(buff))); + else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type) + regval = RegistryValue(new RegistryValueImpl(Name, std::wstring(reinterpret_cast<wchar_t*>(buff)))); + else + assert(false); + + return regval; +} + + +//############################################ +// Commands +//############################################ + + +//----------------------------------------------------- +/** Open the registry key, has no effect if + the key is already open + + @precond IsOpen = false + + @throws RegistryKeyNotFoundException + RegistryWriteAccessDenyException + RegistryAccessDenyException +*/ +void RegistryKeyImplWinNT::Open(bool Writeable) +{ + assert(!IsOpen()); + + REGSAM regsam = KEY_READ; + + if (Writeable) + regsam |= KEY_WRITE; + + LONG rc = RegOpenKeyExW( + m_hRootKey, + m_KeyName.c_str(), + 0, + regsam, + &m_hSubKey); + + if (ERROR_FILE_NOT_FOUND == rc) + throw RegistryKeyNotFoundException(rc); + else if (ERROR_ACCESS_DENIED == rc) + throw RegistryAccessDeniedException(rc); + else if (ERROR_SUCCESS != rc) + throw RegistryException(rc); + + m_IsWriteable = Writeable; + + assert(IsOpen()); +} + +//----------------------------------------------------- +/** Open the specified sub-key of the registry key + at hand + + @precond IsOpen = true + HasSubKey(Name) = true + + @throws RegistryIOException + RegistryKeyNotFoundException + RegistryAccessDeniedException +*/ +RegistryKey RegistryKeyImplWinNT::OpenSubKey(const std::wstring& Name, bool Writeable) +{ + RegistryKey regkey(new RegistryKeyImplWinNT(m_hSubKey, Name)); + regkey->Open(Writeable); + return regkey; +} + +//----------------------------------------------------- +/** Creates a new sub-key below the key at hand + + @precond IsOpen = true + IsWriteable = true + + @throws RegistryIOException + RegistryWriteAccessDenyException +*/ + +RegistryKey RegistryKeyImplWinNT::CreateSubKey(const std::wstring& Name) +{ + assert(IsOpen()); + assert(IsWriteable()); + + HKEY hRoot = IsRootKey() ? m_hRootKey : m_hSubKey; + + HKEY hKey; + + LONG rc = RegCreateKeyExW( + hRoot, + Name.c_str(), + 0, + 0, + REG_OPTION_NON_VOLATILE, + KEY_READ | KEY_WRITE, + 0, + &hKey, + 0); + + if (ERROR_INVALID_HANDLE == rc) + throw RegistryIOException(rc); + else if (ERROR_ACCESS_DENIED == rc) + throw RegistryAccessDeniedException(rc); + else if (ERROR_SUCCESS != rc) + throw RegistryException(rc); + + return RegistryKey(new RegistryKeyImplWinNT(hRoot, hKey, Name)); +} + +//----------------------------------------------------- +/** Deletes a sub-key below the key at hand, the + key must not have sub-keys + + @precond IsOpen = true + IsWriteable = true + + @throws RegistryIOException + RegistryWriteAccessDenyException +*/ +void RegistryKeyImplWinNT::DeleteSubKey(const std::wstring& Name) +{ + assert(IsOpen()); + assert(IsWriteable()); + assert(HasSubKey(Name)); + + RegistryKey SubKey = OpenSubKey(Name); + + size_t nSubKeyCount = SubKey->GetSubKeyCount(); + + assert(0 == nSubKeyCount); + + if (nSubKeyCount) + throw RegistryInvalidOperationException(ERROR_NOT_SUPPORTED); + + LONG rc = RegDeleteKeyW(m_hSubKey, Name.c_str()); + + if (ERROR_INVALID_HANDLE == rc) + throw RegistryIOException(rc); + else if (ERROR_ACCESS_DENIED == rc) + throw RegistryAccessDeniedException(rc); + else if (ERROR_SUCCESS != rc) + throw RegistryException(rc); +} + +//----------------------------------------------------- +/** Deletes a sub-key below the key at hand with all + its sub-keys + + @precond IsOpen = true + IsWriteable = true; + + @throws RegistryIOException + RegistryWriteAccessDenyException +*/ +void RegistryKeyImplWinNT::DeleteSubKeyTree(const std::wstring& Name) +{ + ImplDeleteSubKeyTree(m_hSubKey, Name); +} + +//----------------------------------------------------- +/** Deletes a sub-key below the key at hand with all + its sub-keys + + @precond IsOpen = true + IsWriteable = true; + + @throws RegistryIOException + RegistryWriteAccessDenyException +*/ +LONG RegistryKeyImplWinNT::ImplDeleteSubKeyTree(HKEY RootKey, const std::wstring& Name) +{ + assert(IsOpen()); + + HKEY hKey; + + LONG rc = RegOpenKeyExW( + RootKey, + Name.c_str(), + 0, + KEY_READ | DELETE, + &hKey); + + if (ERROR_SUCCESS == rc) + { + wchar_t* lpSubKey; + DWORD nMaxSubKeyLen; + + rc = RegQueryInfoKeyW( + hKey, 0, 0, 0, 0, + &nMaxSubKeyLen, + 0, 0, 0, 0, 0, 0); + + nMaxSubKeyLen++; // space for trailing '\0' + + lpSubKey = reinterpret_cast<wchar_t*>( + _alloca(nMaxSubKeyLen*sizeof(wchar_t))); + + while (ERROR_SUCCESS == rc) + { + DWORD nLen = nMaxSubKeyLen; + + rc = RegEnumKeyExW( + hKey, + 0, // always index zero + lpSubKey, + &nLen, + 0, 0, 0, 0); + + if (ERROR_NO_MORE_ITEMS == rc) + { + rc = RegDeleteKeyW(RootKey, Name.c_str()); + break; + } + else if (rc == ERROR_SUCCESS) + { + rc = ImplDeleteSubKeyTree(hKey, lpSubKey); + } + + } // while + + RegCloseKey(hKey); + + } // if + + if (ERROR_INVALID_HANDLE == rc) + throw RegistryIOException(rc); + else if (ERROR_ACCESS_DENIED == rc) + throw RegistryAccessDeniedException(rc); + else if (ERROR_FILE_NOT_FOUND == rc) + throw RegistryKeyNotFoundException(rc); + else if (ERROR_SUCCESS != rc) + throw RegistryException(rc); + + return rc; +} + +//----------------------------------------------------- +/** Delete the specified value + + @precond IsOpen = true + IsWriteable = true + HasValue(Name) = true + + @throws RegistryIOException + RegistryWriteAccessDeniedException + RegistryValueNotFoundException +*/ +void RegistryKeyImplWinNT::DeleteValue(const std::wstring& Name) +{ + assert(IsOpen()); + assert(HasValue(Name)); + assert(IsWriteable()); + + LONG rc = RegDeleteValueW( + m_hSubKey, + Name.c_str()); + + if (ERROR_INVALID_HANDLE == rc) + throw RegistryIOException(rc); + else if (ERROR_ACCESS_DENIED == rc) + throw RegistryNoWriteAccessException(rc); + else if (ERROR_FILE_NOT_FOUND == rc) + throw RegistryValueNotFoundException(rc); + else if (ERROR_SUCCESS != rc) + throw RegistryException(rc); +} + +//----------------------------------------------------- +/** Set the specified registry value + + @precond IsOpen = true + IsWriteable = true + + @throws RegistryIOException + RegistryWriteAccessDenyException +*/ +void RegistryKeyImplWinNT::SetValue(const RegistryValue& Value) +{ + assert(IsOpen()); + assert(IsWriteable()); + + LONG rc = RegSetValueExW( + m_hSubKey, + Value->GetName().c_str(), + 0, + Value->GetType(), + reinterpret_cast<const unsigned char*>(Value->GetDataBuffer()), + static_cast<DWORD>(Value->GetDataSize())); + + if (ERROR_INVALID_HANDLE == rc) + throw RegistryIOException(rc); + else if (ERROR_ACCESS_DENIED == rc) + throw RegistryAccessDeniedException(rc); + else if (ERROR_SUCCESS != rc) + throw RegistryException(rc); +} + + + + |