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 ************************************************************************/
30 #pragma warning(push, 1) /* disable warnings within system headers */
38 #include "registrywnt.hxx"
39 #include "registryvalueimpl.hxx"
40 #include "registryexception.hxx"
45 #pragma warning(disable : 4786 4350)
48 const size_t MAX_TMP_BUFF_SIZE
= 1024 * sizeof(wchar_t);
51 //############################################
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 //############################################
85 //############################################
88 //-----------------------------------------------------
89 /** The number of sub values of the key at hand
91 @precond IsOpen = true
95 size_t RegistryKeyImplWinNT::GetSubValueCount() const
101 LONG rc
= RegQueryInfoKeyW(
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
);
113 //-----------------------------------------------------
114 /** The number of sub-keys of the key at hand
116 @precond IsOpen = true
120 size_t RegistryKeyImplWinNT::GetSubKeyCount() const
126 LONG rc
= RegQueryInfoKeyA(
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
);
138 StringListPtr
RegistryKeyImplWinNT::GetSubKeyNames() const
143 DWORD buff_size
= sizeof(buff
);
146 StringList
* key_names
= new StringList();
148 LONG rc
= ERROR_SUCCESS
;
150 for (DWORD i
= 0; /* left empty */; i
++)
153 m_hSubKey
, i
, buff
, &buff_size
,
156 if (ERROR_SUCCESS
!= rc
&&
157 ERROR_MORE_DATA
!= rc
)
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__)
173 return (StringListPtr
) key_names
;
177 StringListPtr
RegistryKeyImplWinNT::GetSubValueNames() const
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
++)
191 m_hSubKey
, i
, buff
, &buff_size
,
194 if (ERROR_SUCCESS
!= rc
&&
195 ERROR_MORE_DATA
!= rc
)
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__)
211 return (StringListPtr
) value_names
;
215 //-----------------------------------------------------
216 /** Get the specified registry value
218 @precond IsOpen = true
220 RegistryValue
RegistryKeyImplWinNT::GetValue(const std::wstring
& Name
) const
225 wchar_t buff
[MAX_TMP_BUFF_SIZE
];
226 DWORD size
= sizeof(buff
);
228 LONG rc
= RegQueryValueExW(
233 reinterpret_cast<LPBYTE
>(buff
),
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
)
252 regval
= RegistryValue(new RegistryValueImpl(Name
, std::wstring(reinterpret_cast<wchar_t*>(buff
))));
254 regval
= RegistryValue(new RegistryValueImpl(Name
, std::wstring()));
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
275 wchar_t buff
[MAX_TMP_BUFF_SIZE
];
276 DWORD size
= sizeof(buff
);
278 LONG rc
= RegQueryValueExW(
283 reinterpret_cast<LPBYTE
>(buff
),
286 if (ERROR_FILE_NOT_FOUND
== rc
)
288 #if (_MSC_VER < 1300) && !defined(__MINGW32__)
291 RegistryValue regval_ptr
;
292 regval_ptr
= RegistryValue(new RegistryValueImpl(*Default
));
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
))));
315 //############################################
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
)
334 REGSAM regsam
= KEY_READ
;
339 LONG rc
= RegOpenKeyExW(
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
;
358 //-----------------------------------------------------
359 /** Open the specified sub-key of the registry key
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
);
376 //-----------------------------------------------------
377 /** Creates a new sub-key below the key at hand
379 @precond IsOpen = true
382 @throws RegistryIOException
383 RegistryWriteAccessDenyException
386 RegistryKey
RegistryKeyImplWinNT::CreateSubKey(const std::wstring
& Name
)
389 assert(IsWriteable());
391 HKEY hRoot
= IsRootKey() ? m_hRootKey
: m_hSubKey
;
395 LONG rc
= RegCreateKeyExW(
400 REG_OPTION_NON_VOLATILE
,
401 KEY_READ
| KEY_WRITE
,
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
423 @throws RegistryIOException
424 RegistryWriteAccessDenyException
426 void RegistryKeyImplWinNT::DeleteSubKey(const std::wstring
& Name
)
429 assert(IsWriteable());
430 assert(HasSubKey(Name
));
432 RegistryKey SubKey
= OpenSubKey(Name
);
434 size_t nSubKeyCount
= SubKey
->GetSubKeyCount();
436 assert(0 == 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
455 @precond IsOpen = 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
470 @precond IsOpen = true
473 @throws RegistryIOException
474 RegistryWriteAccessDenyException
476 LONG
RegistryKeyImplWinNT::ImplDeleteSubKeyTree(HKEY RootKey
, const std::wstring
& Name
)
482 LONG rc
= RegOpenKeyExW(
489 if (ERROR_SUCCESS
== rc
)
494 rc
= RegQueryInfoKeyW(
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
;
510 0, // always index zero
515 if (ERROR_NO_MORE_ITEMS
== rc
)
517 rc
= RegDeleteKeyW(RootKey
, Name
.c_str());
520 else if (rc
== ERROR_SUCCESS
)
522 rc
= ImplDeleteSubKeyTree(hKey
, lpSubKey
);
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
);
543 //-----------------------------------------------------
544 /** Delete the specified value
546 @precond IsOpen = true
548 HasValue(Name) = true
550 @throws RegistryIOException
551 RegistryWriteAccessDeniedException
552 RegistryValueNotFoundException
554 void RegistryKeyImplWinNT::DeleteValue(const std::wstring
& Name
)
557 assert(HasValue(Name
));
558 assert(IsWriteable());
560 LONG rc
= RegDeleteValueW(
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
580 @throws RegistryIOException
581 RegistryWriteAccessDenyException
583 void RegistryKeyImplWinNT::SetValue(const RegistryValue
& Value
)
586 assert(IsWriteable());
588 LONG rc
= RegSetValueExW(
590 Value
->GetName().c_str(),
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: */