1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: registrywnt.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 //---------------------------------------
33 //---------------------------------------
36 #pragma warning(push, 1) /* disable warnings within system headers */
44 #include "registrywnt.hxx"
45 #include "registryvalueimpl.hxx"
46 #include "registryexception.hxx"
51 #pragma warning(disable : 4786 4350)
54 //---------------------------------------
56 //---------------------------------------
58 const size_t MAX_TMP_BUFF_SIZE
= 1024 * sizeof(wchar_t);
61 //############################################
63 // only possible through WindowsRegistry class
64 //############################################
67 //-----------------------------------------------------
68 /** Create instance and open the specified Registry key
70 RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey
, const std::wstring
& KeyName
) :
71 RegistryKeyImpl(RootKey
, KeyName
)
75 //-----------------------------------------------------
76 /** Create instance and open the specified Registry key
78 RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey
) :
79 RegistryKeyImpl(RootKey
)
83 //-----------------------------------------------------
84 /** Create an instances of the specified Registry key,
85 the key is assumed to be already opened.
87 RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey
, HKEY SubKey
, const std::wstring
& KeyName
, bool Writeable
) :
88 RegistryKeyImpl(RootKey
, SubKey
, KeyName
, Writeable
)
93 //############################################
95 //############################################
98 //-----------------------------------------------------
99 /** The number of sub values of the key at hand
101 @precond IsOpen = true
105 size_t RegistryKeyImplWinNT::GetSubValueCount() const
109 DWORD nSubValues
= 0;
111 LONG rc
= RegQueryInfoKeyW(
113 0, 0, 0, 0, 0, 0, &nSubValues
, 0, 0, 0, 0);
115 if (ERROR_INVALID_HANDLE
== rc
)
116 throw RegistryIOException(rc
);
117 else if (ERROR_SUCCESS
!= rc
)
118 throw RegistryException(rc
);
123 //-----------------------------------------------------
124 /** The number of sub-keys of the key at hand
126 @precond IsOpen = true
130 size_t RegistryKeyImplWinNT::GetSubKeyCount() const
136 LONG rc
= RegQueryInfoKeyA(
138 0, 0, 0, &nSubKeys
, 0, 0, 0, 0, 0, 0, 0);
140 if (ERROR_INVALID_HANDLE
== rc
)
141 throw RegistryIOException(rc
);
142 else if (ERROR_SUCCESS
!= rc
)
143 throw RegistryException(rc
);
148 //-----------------------------------------------------
151 StringListPtr
RegistryKeyImplWinNT::GetSubKeyNames() const
156 DWORD buff_size
= sizeof(buff
);
159 StringList
* key_names
= new StringList();
161 LONG rc
= ERROR_SUCCESS
;
163 for (DWORD i
= 0; /* left empty */; i
++)
166 m_hSubKey
, i
, buff
, &buff_size
,
169 if (ERROR_SUCCESS
!= rc
&&
170 ERROR_MORE_DATA
!= rc
)
173 buff_size
= sizeof(buff
);
175 key_names
->push_back(buff
);
178 if (ERROR_INVALID_HANDLE
== rc
)
179 throw RegistryIOException(rc
);
180 else if (ERROR_NO_MORE_ITEMS
!= rc
&& ERROR_SUCCESS
!= rc
)
181 throw RegistryException(rc
);
183 #if (_MSC_VER < 1300) && !defined(__MINGW32__)
186 return (StringListPtr
) key_names
;
190 //-----------------------------------------------------
193 StringListPtr
RegistryKeyImplWinNT::GetSubValueNames() const
198 DWORD buff_size
= sizeof(buff
);
200 StringList
* value_names
= new StringList();
202 LONG rc
= ERROR_SUCCESS
;
204 for (DWORD i
= 0; /* left empty */; i
++)
207 m_hSubKey
, i
, buff
, &buff_size
,
210 if (ERROR_SUCCESS
!= rc
&&
211 ERROR_MORE_DATA
!= rc
)
214 buff_size
= sizeof(buff
);
216 value_names
->push_back(buff
);
219 if (ERROR_INVALID_HANDLE
== rc
)
220 throw RegistryIOException(rc
);
221 else if (ERROR_NO_MORE_ITEMS
!= rc
&& ERROR_SUCCESS
!= rc
)
222 throw RegistryException(rc
);
224 #if (_MSC_VER < 1300) && !defined(__MINGW32__)
227 return (StringListPtr
) value_names
;
231 //-----------------------------------------------------
232 /** Get the specified registry value
234 @precond IsOpen = true
236 RegistryValue
RegistryKeyImplWinNT::GetValue(const std::wstring
& Name
) const
241 wchar_t buff
[MAX_TMP_BUFF_SIZE
];
242 DWORD size
= sizeof(buff
);
244 LONG rc
= RegQueryValueExW(
249 reinterpret_cast<LPBYTE
>(buff
),
252 if (ERROR_FILE_NOT_FOUND
== rc
)
253 throw RegistryValueNotFoundException(rc
);
254 else if (ERROR_ACCESS_DENIED
== rc
)
255 throw RegistryAccessDeniedException(rc
);
256 else if (ERROR_SUCCESS
!= rc
)
257 throw RegistryException(rc
);
259 RegistryValue regval
;
261 if (REG_DWORD
== Type
)
263 regval
= RegistryValue(new RegistryValueImpl(Name
, *(reinterpret_cast<int*>(buff
))));
265 else if (REG_SZ
== Type
|| REG_EXPAND_SZ
== Type
|| REG_MULTI_SZ
== Type
)
268 regval
= RegistryValue(new RegistryValueImpl(Name
, std::wstring(reinterpret_cast<wchar_t*>(buff
))));
270 regval
= RegistryValue(new RegistryValueImpl(Name
, std::wstring()));
280 //-----------------------------------------------------
281 /** Get the specified registry value, return the given
282 default value if value not found
284 @precond IsOpen = true
286 RegistryValue
RegistryKeyImplWinNT::GetValue(const std::wstring
& Name
, const RegistryValue
& Default
) const
291 wchar_t buff
[MAX_TMP_BUFF_SIZE
];
292 DWORD size
= sizeof(buff
);
294 LONG rc
= RegQueryValueExW(
299 reinterpret_cast<LPBYTE
>(buff
),
302 if (ERROR_FILE_NOT_FOUND
== rc
)
304 #if (_MSC_VER < 1300) && !defined(__MINGW32__)
307 RegistryValue regval_ptr
;
308 regval_ptr
= RegistryValue(new RegistryValueImpl(*Default
));
313 if (ERROR_ACCESS_DENIED
== rc
)
314 throw RegistryAccessDeniedException(rc
);
315 else if (ERROR_SUCCESS
!= rc
)
316 throw RegistryException(rc
);
318 RegistryValue regval
;
320 if (REG_DWORD
== Type
)
321 regval
= RegistryValue(new RegistryValueImpl(Name
, *reinterpret_cast<int*>(buff
)));
322 else if (REG_SZ
== Type
|| REG_EXPAND_SZ
== Type
|| REG_MULTI_SZ
== Type
)
323 regval
= RegistryValue(new RegistryValueImpl(Name
, std::wstring(reinterpret_cast<wchar_t*>(buff
))));
331 //############################################
333 //############################################
336 //-----------------------------------------------------
337 /** Open the registry key, has no effect if
338 the key is already open
340 @precond IsOpen = false
342 @throws RegistryKeyNotFoundException
343 RegistryWriteAccessDenyException
344 RegistryAccessDenyException
346 void RegistryKeyImplWinNT::Open(bool Writeable
)
350 REGSAM regsam
= KEY_READ
;
355 LONG rc
= RegOpenKeyExW(
362 if (ERROR_FILE_NOT_FOUND
== rc
)
363 throw RegistryKeyNotFoundException(rc
);
364 else if (ERROR_ACCESS_DENIED
== rc
)
365 throw RegistryAccessDeniedException(rc
);
366 else if (ERROR_SUCCESS
!= rc
)
367 throw RegistryException(rc
);
369 m_IsWriteable
= Writeable
;
374 //-----------------------------------------------------
375 /** Open the specified sub-key of the registry key
378 @precond IsOpen = true
379 HasSubKey(Name) = true
381 @throws RegistryIOException
382 RegistryKeyNotFoundException
383 RegistryAccessDeniedException
385 RegistryKey
RegistryKeyImplWinNT::OpenSubKey(const std::wstring
& Name
, bool Writeable
)
387 RegistryKey
regkey(new RegistryKeyImplWinNT(m_hSubKey
, Name
));
388 regkey
->Open(Writeable
);
392 //-----------------------------------------------------
393 /** Creates a new sub-key below the key at hand
395 @precond IsOpen = true
398 @throws RegistryIOException
399 RegistryWriteAccessDenyException
402 RegistryKey
RegistryKeyImplWinNT::CreateSubKey(const std::wstring
& Name
)
405 assert(IsWriteable());
407 HKEY hRoot
= IsRootKey() ? m_hRootKey
: m_hSubKey
;
411 LONG rc
= RegCreateKeyExW(
416 REG_OPTION_NON_VOLATILE
,
417 KEY_READ
| KEY_WRITE
,
422 if (ERROR_INVALID_HANDLE
== rc
)
423 throw RegistryIOException(rc
);
424 else if (ERROR_ACCESS_DENIED
== rc
)
425 throw RegistryAccessDeniedException(rc
);
426 else if (ERROR_SUCCESS
!= rc
)
427 throw RegistryException(rc
);
429 return RegistryKey(new RegistryKeyImplWinNT(hRoot
, hKey
, Name
));
432 //-----------------------------------------------------
433 /** Deletes a sub-key below the key at hand, the
434 key must not have sub-keys
436 @precond IsOpen = true
439 @throws RegistryIOException
440 RegistryWriteAccessDenyException
442 void RegistryKeyImplWinNT::DeleteSubKey(const std::wstring
& Name
)
445 assert(IsWriteable());
446 assert(HasSubKey(Name
));
448 RegistryKey SubKey
= OpenSubKey(Name
);
450 size_t nSubKeyCount
= SubKey
->GetSubKeyCount();
452 assert(0 == nSubKeyCount
);
455 throw RegistryInvalidOperationException(ERROR_NOT_SUPPORTED
);
457 LONG rc
= RegDeleteKeyW(m_hSubKey
, Name
.c_str());
459 if (ERROR_INVALID_HANDLE
== rc
)
460 throw RegistryIOException(rc
);
461 else if (ERROR_ACCESS_DENIED
== rc
)
462 throw RegistryAccessDeniedException(rc
);
463 else if (ERROR_SUCCESS
!= rc
)
464 throw RegistryException(rc
);
467 //-----------------------------------------------------
468 /** Deletes a sub-key below the key at hand with all
471 @precond IsOpen = true
474 @throws RegistryIOException
475 RegistryWriteAccessDenyException
477 void RegistryKeyImplWinNT::DeleteSubKeyTree(const std::wstring
& Name
)
479 ImplDeleteSubKeyTree(m_hSubKey
, Name
);
482 //-----------------------------------------------------
483 /** Deletes a sub-key below the key at hand with all
486 @precond IsOpen = true
489 @throws RegistryIOException
490 RegistryWriteAccessDenyException
492 LONG
RegistryKeyImplWinNT::ImplDeleteSubKeyTree(HKEY RootKey
, const std::wstring
& Name
)
498 LONG rc
= RegOpenKeyExW(
505 if (ERROR_SUCCESS
== rc
)
510 rc
= RegQueryInfoKeyW(
515 nMaxSubKeyLen
++; // space for trailing '\0'
517 lpSubKey
= reinterpret_cast<wchar_t*>(
518 _alloca(nMaxSubKeyLen
*sizeof(wchar_t)));
520 while (ERROR_SUCCESS
== rc
)
522 DWORD nLen
= nMaxSubKeyLen
;
526 0, // always index zero
531 if (ERROR_NO_MORE_ITEMS
== rc
)
533 rc
= RegDeleteKeyW(RootKey
, Name
.c_str());
536 else if (rc
== ERROR_SUCCESS
)
538 rc
= ImplDeleteSubKeyTree(hKey
, lpSubKey
);
547 if (ERROR_INVALID_HANDLE
== rc
)
548 throw RegistryIOException(rc
);
549 else if (ERROR_ACCESS_DENIED
== rc
)
550 throw RegistryAccessDeniedException(rc
);
551 else if (ERROR_FILE_NOT_FOUND
== rc
)
552 throw RegistryKeyNotFoundException(rc
);
553 else if (ERROR_SUCCESS
!= rc
)
554 throw RegistryException(rc
);
559 //-----------------------------------------------------
560 /** Delete the specified value
562 @precond IsOpen = true
564 HasValue(Name) = true
566 @throws RegistryIOException
567 RegistryWriteAccessDeniedException
568 RegistryValueNotFoundException
570 void RegistryKeyImplWinNT::DeleteValue(const std::wstring
& Name
)
573 assert(HasValue(Name
));
574 assert(IsWriteable());
576 LONG rc
= RegDeleteValueW(
580 if (ERROR_INVALID_HANDLE
== rc
)
581 throw RegistryIOException(rc
);
582 else if (ERROR_ACCESS_DENIED
== rc
)
583 throw RegistryNoWriteAccessException(rc
);
584 else if (ERROR_FILE_NOT_FOUND
== rc
)
585 throw RegistryValueNotFoundException(rc
);
586 else if (ERROR_SUCCESS
!= rc
)
587 throw RegistryException(rc
);
590 //-----------------------------------------------------
591 /** Set the specified registry value
593 @precond IsOpen = true
596 @throws RegistryIOException
597 RegistryWriteAccessDenyException
599 void RegistryKeyImplWinNT::SetValue(const RegistryValue
& Value
)
602 assert(IsWriteable());
604 LONG rc
= RegSetValueExW(
606 Value
->GetName().c_str(),
609 reinterpret_cast<const unsigned char*>(Value
->GetDataBuffer()),
610 static_cast<DWORD
>(Value
->GetDataSize()));
612 if (ERROR_INVALID_HANDLE
== rc
)
613 throw RegistryIOException(rc
);
614 else if (ERROR_ACCESS_DENIED
== rc
)
615 throw RegistryAccessDeniedException(rc
);
616 else if (ERROR_SUCCESS
!= rc
)
617 throw RegistryException(rc
);