Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / setup_native / source / win32 / customactions / reg4msdoc / registrywnt.cxx
blob8776e0edd0e067e5c1399a36ff301ecaf7e5da41
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #ifdef _MSC_VER
30 #pragma warning(push, 1) /* disable warnings within system headers */
31 #endif
32 #include <windows.h>
33 #ifdef _MSC_VER
34 #pragma warning(pop)
35 #endif
37 #include <malloc.h>
38 #include "registrywnt.hxx"
39 #include "registryvalueimpl.hxx"
40 #include "registryexception.hxx"
42 #include <assert.h>
44 #ifdef _MSC_VER
45 #pragma warning(disable : 4786 4350)
46 #endif
48 const size_t MAX_TMP_BUFF_SIZE = 1024 * sizeof(wchar_t);
51 //############################################
52 // Creation
53 // only possible through WindowsRegistry class
54 //############################################
57 //-----------------------------------------------------
58 /** Create instance and open the specified Registry key
60 RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey, const std::wstring& KeyName) :
61 RegistryKeyImpl(RootKey, KeyName)
65 //-----------------------------------------------------
66 /** Create instance and open the specified Registry key
68 RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey) :
69 RegistryKeyImpl(RootKey)
73 //-----------------------------------------------------
74 /** Create an instances of the specified Registry key,
75 the key is assumed to be already opened.
77 RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable) :
78 RegistryKeyImpl(RootKey, SubKey, KeyName, Writeable)
83 //############################################
84 // Queries
85 //############################################
88 //-----------------------------------------------------
89 /** The number of sub values of the key at hand
91 @precond IsOpen = true
93 @throws
95 size_t RegistryKeyImplWinNT::GetSubValueCount() const
97 assert(IsOpen());
99 DWORD nSubValues = 0;
101 LONG rc = RegQueryInfoKeyW(
102 m_hSubKey,
103 0, 0, 0, 0, 0, 0, &nSubValues, 0, 0, 0, 0);
105 if (ERROR_INVALID_HANDLE == rc)
106 throw RegistryIOException(rc);
107 else if (ERROR_SUCCESS != rc)
108 throw RegistryException(rc);
110 return nSubValues;
113 //-----------------------------------------------------
114 /** The number of sub-keys of the key at hand
116 @precond IsOpen = true
118 @throws
120 size_t RegistryKeyImplWinNT::GetSubKeyCount() const
122 assert(IsOpen());
124 DWORD nSubKeys = 0;
126 LONG rc = RegQueryInfoKeyA(
127 m_hSubKey,
128 0, 0, 0, &nSubKeys, 0, 0, 0, 0, 0, 0, 0);
130 if (ERROR_INVALID_HANDLE == rc)
131 throw RegistryIOException(rc);
132 else if (ERROR_SUCCESS != rc)
133 throw RegistryException(rc);
135 return nSubKeys;
138 StringListPtr RegistryKeyImplWinNT::GetSubKeyNames() const
140 assert(IsOpen());
142 wchar_t buff[1024];
143 DWORD buff_size = sizeof(buff);
144 FILETIME ftime;
146 StringList* key_names = new StringList();
148 LONG rc = ERROR_SUCCESS;
150 for (DWORD i = 0; /* left empty */; i++)
152 rc = RegEnumKeyExW(
153 m_hSubKey, i, buff, &buff_size,
154 0, 0, 0, &ftime);
156 if (ERROR_SUCCESS != rc &&
157 ERROR_MORE_DATA != rc)
158 break;
160 buff_size = sizeof(buff);
162 key_names->push_back(buff);
165 if (ERROR_INVALID_HANDLE == rc)
166 throw RegistryIOException(rc);
167 else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
168 throw RegistryException(rc);
170 #if (_MSC_VER < 1300) && !defined(__MINGW32__)
171 return key_names;
172 #else
173 return (StringListPtr) key_names;
174 #endif
177 StringListPtr RegistryKeyImplWinNT::GetSubValueNames() const
179 assert(IsOpen());
181 wchar_t buff[1024];
182 DWORD buff_size = sizeof(buff);
184 StringList* value_names = new StringList();
186 LONG rc = ERROR_SUCCESS;
188 for (DWORD i = 0; /* left empty */; i++)
190 rc = RegEnumValueW(
191 m_hSubKey, i, buff, &buff_size,
192 0, 0, 0, 0);
194 if (ERROR_SUCCESS != rc &&
195 ERROR_MORE_DATA != rc)
196 break;
198 buff_size = sizeof(buff);
200 value_names->push_back(buff);
203 if (ERROR_INVALID_HANDLE == rc)
204 throw RegistryIOException(rc);
205 else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
206 throw RegistryException(rc);
208 #if (_MSC_VER < 1300) && !defined(__MINGW32__)
209 return value_names;
210 #else
211 return (StringListPtr) value_names;
212 #endif
215 //-----------------------------------------------------
216 /** Get the specified registry value
218 @precond IsOpen = true
220 RegistryValue RegistryKeyImplWinNT::GetValue(const std::wstring& Name) const
222 assert(IsOpen());
224 DWORD Type;
225 wchar_t buff[MAX_TMP_BUFF_SIZE];
226 DWORD size = sizeof(buff);
228 LONG rc = RegQueryValueExW(
229 m_hSubKey,
230 Name.c_str(),
232 &Type,
233 reinterpret_cast<LPBYTE>(buff),
234 &size);
236 if (ERROR_FILE_NOT_FOUND == rc)
237 throw RegistryValueNotFoundException(rc);
238 else if (ERROR_ACCESS_DENIED == rc)
239 throw RegistryAccessDeniedException(rc);
240 else if (ERROR_SUCCESS != rc)
241 throw RegistryException(rc);
243 RegistryValue regval;
245 if (REG_DWORD == Type)
247 regval = RegistryValue(new RegistryValueImpl(Name, *(reinterpret_cast<int*>(buff))));
249 else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
251 if (size > 0)
252 regval = RegistryValue(new RegistryValueImpl(Name, std::wstring(reinterpret_cast<wchar_t*>(buff))));
253 else
254 regval = RegistryValue(new RegistryValueImpl(Name, std::wstring()));
256 else
258 assert(false);
261 return regval;
264 //-----------------------------------------------------
265 /** Get the specified registry value, return the given
266 default value if value not found
268 @precond IsOpen = true
270 RegistryValue RegistryKeyImplWinNT::GetValue(const std::wstring& Name, const RegistryValue& Default) const
272 assert(IsOpen());
274 DWORD Type;
275 wchar_t buff[MAX_TMP_BUFF_SIZE];
276 DWORD size = sizeof(buff);
278 LONG rc = RegQueryValueExW(
279 m_hSubKey,
280 Name.c_str(),
282 &Type,
283 reinterpret_cast<LPBYTE>(buff),
284 &size);
286 if (ERROR_FILE_NOT_FOUND == rc)
288 #if (_MSC_VER < 1300) && !defined(__MINGW32__)
289 return Default;
290 #else
291 RegistryValue regval_ptr;
292 regval_ptr = RegistryValue(new RegistryValueImpl(*Default));
293 return regval_ptr;
294 #endif
297 if (ERROR_ACCESS_DENIED == rc)
298 throw RegistryAccessDeniedException(rc);
299 else if (ERROR_SUCCESS != rc)
300 throw RegistryException(rc);
302 RegistryValue regval;
304 if (REG_DWORD == Type)
305 regval = RegistryValue(new RegistryValueImpl(Name, *reinterpret_cast<int*>(buff)));
306 else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
307 regval = RegistryValue(new RegistryValueImpl(Name, std::wstring(reinterpret_cast<wchar_t*>(buff))));
308 else
309 assert(false);
311 return regval;
315 //############################################
316 // Commands
317 //############################################
320 //-----------------------------------------------------
321 /** Open the registry key, has no effect if
322 the key is already open
324 @precond IsOpen = false
326 @throws RegistryKeyNotFoundException
327 RegistryWriteAccessDenyException
328 RegistryAccessDenyException
330 void RegistryKeyImplWinNT::Open(bool Writeable)
332 assert(!IsOpen());
334 REGSAM regsam = KEY_READ;
336 if (Writeable)
337 regsam |= KEY_WRITE;
339 LONG rc = RegOpenKeyExW(
340 m_hRootKey,
341 m_KeyName.c_str(),
343 regsam,
344 &m_hSubKey);
346 if (ERROR_FILE_NOT_FOUND == rc)
347 throw RegistryKeyNotFoundException(rc);
348 else if (ERROR_ACCESS_DENIED == rc)
349 throw RegistryAccessDeniedException(rc);
350 else if (ERROR_SUCCESS != rc)
351 throw RegistryException(rc);
353 m_IsWriteable = Writeable;
355 assert(IsOpen());
358 //-----------------------------------------------------
359 /** Open the specified sub-key of the registry key
360 at hand
362 @precond IsOpen = true
363 HasSubKey(Name) = true
365 @throws RegistryIOException
366 RegistryKeyNotFoundException
367 RegistryAccessDeniedException
369 RegistryKey RegistryKeyImplWinNT::OpenSubKey(const std::wstring& Name, bool Writeable)
371 RegistryKey regkey(new RegistryKeyImplWinNT(m_hSubKey, Name));
372 regkey->Open(Writeable);
373 return regkey;
376 //-----------------------------------------------------
377 /** Creates a new sub-key below the key at hand
379 @precond IsOpen = true
380 IsWriteable = true
382 @throws RegistryIOException
383 RegistryWriteAccessDenyException
386 RegistryKey RegistryKeyImplWinNT::CreateSubKey(const std::wstring& Name)
388 assert(IsOpen());
389 assert(IsWriteable());
391 HKEY hRoot = IsRootKey() ? m_hRootKey : m_hSubKey;
393 HKEY hKey;
395 LONG rc = RegCreateKeyExW(
396 hRoot,
397 Name.c_str(),
400 REG_OPTION_NON_VOLATILE,
401 KEY_READ | KEY_WRITE,
403 &hKey,
406 if (ERROR_INVALID_HANDLE == rc)
407 throw RegistryIOException(rc);
408 else if (ERROR_ACCESS_DENIED == rc)
409 throw RegistryAccessDeniedException(rc);
410 else if (ERROR_SUCCESS != rc)
411 throw RegistryException(rc);
413 return RegistryKey(new RegistryKeyImplWinNT(hRoot, hKey, Name));
416 //-----------------------------------------------------
417 /** Deletes a sub-key below the key at hand, the
418 key must not have sub-keys
420 @precond IsOpen = true
421 IsWriteable = true
423 @throws RegistryIOException
424 RegistryWriteAccessDenyException
426 void RegistryKeyImplWinNT::DeleteSubKey(const std::wstring& Name)
428 assert(IsOpen());
429 assert(IsWriteable());
430 assert(HasSubKey(Name));
432 RegistryKey SubKey = OpenSubKey(Name);
434 size_t nSubKeyCount = SubKey->GetSubKeyCount();
436 assert(0 == nSubKeyCount);
438 if (nSubKeyCount)
439 throw RegistryInvalidOperationException(ERROR_NOT_SUPPORTED);
441 LONG rc = RegDeleteKeyW(m_hSubKey, Name.c_str());
443 if (ERROR_INVALID_HANDLE == rc)
444 throw RegistryIOException(rc);
445 else if (ERROR_ACCESS_DENIED == rc)
446 throw RegistryAccessDeniedException(rc);
447 else if (ERROR_SUCCESS != rc)
448 throw RegistryException(rc);
451 //-----------------------------------------------------
452 /** Deletes a sub-key below the key at hand with all
453 its sub-keys
455 @precond IsOpen = true
456 IsWriteable = true;
458 @throws RegistryIOException
459 RegistryWriteAccessDenyException
461 void RegistryKeyImplWinNT::DeleteSubKeyTree(const std::wstring& Name)
463 ImplDeleteSubKeyTree(m_hSubKey, Name);
466 //-----------------------------------------------------
467 /** Deletes a sub-key below the key at hand with all
468 its sub-keys
470 @precond IsOpen = true
471 IsWriteable = true;
473 @throws RegistryIOException
474 RegistryWriteAccessDenyException
476 LONG RegistryKeyImplWinNT::ImplDeleteSubKeyTree(HKEY RootKey, const std::wstring& Name)
478 assert(IsOpen());
480 HKEY hKey;
482 LONG rc = RegOpenKeyExW(
483 RootKey,
484 Name.c_str(),
486 KEY_READ | DELETE,
487 &hKey);
489 if (ERROR_SUCCESS == rc)
491 wchar_t* lpSubKey;
492 DWORD nMaxSubKeyLen;
494 rc = RegQueryInfoKeyW(
495 hKey, 0, 0, 0, 0,
496 &nMaxSubKeyLen,
497 0, 0, 0, 0, 0, 0);
499 nMaxSubKeyLen++; // space for trailing '\0'
501 lpSubKey = reinterpret_cast<wchar_t*>(
502 _alloca(nMaxSubKeyLen*sizeof(wchar_t)));
504 while (ERROR_SUCCESS == rc)
506 DWORD nLen = nMaxSubKeyLen;
508 rc = RegEnumKeyExW(
509 hKey,
510 0, // always index zero
511 lpSubKey,
512 &nLen,
513 0, 0, 0, 0);
515 if (ERROR_NO_MORE_ITEMS == rc)
517 rc = RegDeleteKeyW(RootKey, Name.c_str());
518 break;
520 else if (rc == ERROR_SUCCESS)
522 rc = ImplDeleteSubKeyTree(hKey, lpSubKey);
525 } // while
527 RegCloseKey(hKey);
529 } // if
531 if (ERROR_INVALID_HANDLE == rc)
532 throw RegistryIOException(rc);
533 else if (ERROR_ACCESS_DENIED == rc)
534 throw RegistryAccessDeniedException(rc);
535 else if (ERROR_FILE_NOT_FOUND == rc)
536 throw RegistryKeyNotFoundException(rc);
537 else if (ERROR_SUCCESS != rc)
538 throw RegistryException(rc);
540 return rc;
543 //-----------------------------------------------------
544 /** Delete the specified value
546 @precond IsOpen = true
547 IsWriteable = true
548 HasValue(Name) = true
550 @throws RegistryIOException
551 RegistryWriteAccessDeniedException
552 RegistryValueNotFoundException
554 void RegistryKeyImplWinNT::DeleteValue(const std::wstring& Name)
556 assert(IsOpen());
557 assert(HasValue(Name));
558 assert(IsWriteable());
560 LONG rc = RegDeleteValueW(
561 m_hSubKey,
562 Name.c_str());
564 if (ERROR_INVALID_HANDLE == rc)
565 throw RegistryIOException(rc);
566 else if (ERROR_ACCESS_DENIED == rc)
567 throw RegistryNoWriteAccessException(rc);
568 else if (ERROR_FILE_NOT_FOUND == rc)
569 throw RegistryValueNotFoundException(rc);
570 else if (ERROR_SUCCESS != rc)
571 throw RegistryException(rc);
574 //-----------------------------------------------------
575 /** Set the specified registry value
577 @precond IsOpen = true
578 IsWriteable = true
580 @throws RegistryIOException
581 RegistryWriteAccessDenyException
583 void RegistryKeyImplWinNT::SetValue(const RegistryValue& Value)
585 assert(IsOpen());
586 assert(IsWriteable());
588 LONG rc = RegSetValueExW(
589 m_hSubKey,
590 Value->GetName().c_str(),
592 Value->GetType(),
593 reinterpret_cast<const unsigned char*>(Value->GetDataBuffer()),
594 static_cast<DWORD>(Value->GetDataSize()));
596 if (ERROR_INVALID_HANDLE == rc)
597 throw RegistryIOException(rc);
598 else if (ERROR_ACCESS_DENIED == rc)
599 throw RegistryAccessDeniedException(rc);
600 else if (ERROR_SUCCESS != rc)
601 throw RegistryException(rc);
607 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */