Update ooo320-m1
[ooovba.git] / setup_native / source / win32 / customactions / reg4msdoc / registrywnt.cxx
blob3d574870910714f95123ffdc5c715b007d761e20
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: registrywnt.cxx,v $
10 * $Revision: 1.7 $
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 //---------------------------------------
32 //
33 //---------------------------------------
35 #ifdef _MSC_VER
36 #pragma warning(push, 1) /* disable warnings within system headers */
37 #endif
38 #include <windows.h>
39 #ifdef _MSC_VER
40 #pragma warning(pop)
41 #endif
43 #include <malloc.h>
44 #include "registrywnt.hxx"
45 #include "registryvalueimpl.hxx"
46 #include "registryexception.hxx"
48 #include <assert.h>
50 #ifdef _MSC_VER
51 #pragma warning(disable : 4786 4350)
52 #endif
54 //---------------------------------------
55 //
56 //---------------------------------------
58 const size_t MAX_TMP_BUFF_SIZE = 1024 * sizeof(wchar_t);
61 //############################################
62 // Creation
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 //############################################
94 // Queries
95 //############################################
98 //-----------------------------------------------------
99 /** The number of sub values of the key at hand
101 @precond IsOpen = true
103 @throws
105 size_t RegistryKeyImplWinNT::GetSubValueCount() const
107 assert(IsOpen());
109 DWORD nSubValues = 0;
111 LONG rc = RegQueryInfoKeyW(
112 m_hSubKey,
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);
120 return nSubValues;
123 //-----------------------------------------------------
124 /** The number of sub-keys of the key at hand
126 @precond IsOpen = true
128 @throws
130 size_t RegistryKeyImplWinNT::GetSubKeyCount() const
132 assert(IsOpen());
134 DWORD nSubKeys = 0;
136 LONG rc = RegQueryInfoKeyA(
137 m_hSubKey,
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);
145 return nSubKeys;
148 //-----------------------------------------------------
151 StringListPtr RegistryKeyImplWinNT::GetSubKeyNames() const
153 assert(IsOpen());
155 wchar_t buff[1024];
156 DWORD buff_size = sizeof(buff);
157 FILETIME ftime;
159 StringList* key_names = new StringList();
161 LONG rc = ERROR_SUCCESS;
163 for (DWORD i = 0; /* left empty */; i++)
165 rc = RegEnumKeyExW(
166 m_hSubKey, i, buff, &buff_size,
167 0, 0, 0, &ftime);
169 if (ERROR_SUCCESS != rc &&
170 ERROR_MORE_DATA != rc)
171 break;
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__)
184 return key_names;
185 #else
186 return (StringListPtr) key_names;
187 #endif
190 //-----------------------------------------------------
193 StringListPtr RegistryKeyImplWinNT::GetSubValueNames() const
195 assert(IsOpen());
197 wchar_t buff[1024];
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++)
206 rc = RegEnumValueW(
207 m_hSubKey, i, buff, &buff_size,
208 0, 0, 0, 0);
210 if (ERROR_SUCCESS != rc &&
211 ERROR_MORE_DATA != rc)
212 break;
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__)
225 return value_names;
226 #else
227 return (StringListPtr) value_names;
228 #endif
231 //-----------------------------------------------------
232 /** Get the specified registry value
234 @precond IsOpen = true
236 RegistryValue RegistryKeyImplWinNT::GetValue(const std::wstring& Name) const
238 assert(IsOpen());
240 DWORD Type;
241 wchar_t buff[MAX_TMP_BUFF_SIZE];
242 DWORD size = sizeof(buff);
244 LONG rc = RegQueryValueExW(
245 m_hSubKey,
246 Name.c_str(),
248 &Type,
249 reinterpret_cast<LPBYTE>(buff),
250 &size);
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)
267 if (size > 0)
268 regval = RegistryValue(new RegistryValueImpl(Name, std::wstring(reinterpret_cast<wchar_t*>(buff))));
269 else
270 regval = RegistryValue(new RegistryValueImpl(Name, std::wstring()));
272 else
274 assert(false);
277 return regval;
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
288 assert(IsOpen());
290 DWORD Type;
291 wchar_t buff[MAX_TMP_BUFF_SIZE];
292 DWORD size = sizeof(buff);
294 LONG rc = RegQueryValueExW(
295 m_hSubKey,
296 Name.c_str(),
298 &Type,
299 reinterpret_cast<LPBYTE>(buff),
300 &size);
302 if (ERROR_FILE_NOT_FOUND == rc)
304 #if (_MSC_VER < 1300) && !defined(__MINGW32__)
305 return Default;
306 #else
307 RegistryValue regval_ptr;
308 regval_ptr = RegistryValue(new RegistryValueImpl(*Default));
309 return regval_ptr;
310 #endif
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))));
324 else
325 assert(false);
327 return regval;
331 //############################################
332 // Commands
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)
348 assert(!IsOpen());
350 REGSAM regsam = KEY_READ;
352 if (Writeable)
353 regsam |= KEY_WRITE;
355 LONG rc = RegOpenKeyExW(
356 m_hRootKey,
357 m_KeyName.c_str(),
359 regsam,
360 &m_hSubKey);
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;
371 assert(IsOpen());
374 //-----------------------------------------------------
375 /** Open the specified sub-key of the registry key
376 at hand
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);
389 return regkey;
392 //-----------------------------------------------------
393 /** Creates a new sub-key below the key at hand
395 @precond IsOpen = true
396 IsWriteable = true
398 @throws RegistryIOException
399 RegistryWriteAccessDenyException
402 RegistryKey RegistryKeyImplWinNT::CreateSubKey(const std::wstring& Name)
404 assert(IsOpen());
405 assert(IsWriteable());
407 HKEY hRoot = IsRootKey() ? m_hRootKey : m_hSubKey;
409 HKEY hKey;
411 LONG rc = RegCreateKeyExW(
412 hRoot,
413 Name.c_str(),
416 REG_OPTION_NON_VOLATILE,
417 KEY_READ | KEY_WRITE,
419 &hKey,
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
437 IsWriteable = true
439 @throws RegistryIOException
440 RegistryWriteAccessDenyException
442 void RegistryKeyImplWinNT::DeleteSubKey(const std::wstring& Name)
444 assert(IsOpen());
445 assert(IsWriteable());
446 assert(HasSubKey(Name));
448 RegistryKey SubKey = OpenSubKey(Name);
450 size_t nSubKeyCount = SubKey->GetSubKeyCount();
452 assert(0 == nSubKeyCount);
454 if (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
469 its sub-keys
471 @precond IsOpen = true
472 IsWriteable = 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
484 its sub-keys
486 @precond IsOpen = true
487 IsWriteable = true;
489 @throws RegistryIOException
490 RegistryWriteAccessDenyException
492 LONG RegistryKeyImplWinNT::ImplDeleteSubKeyTree(HKEY RootKey, const std::wstring& Name)
494 assert(IsOpen());
496 HKEY hKey;
498 LONG rc = RegOpenKeyExW(
499 RootKey,
500 Name.c_str(),
502 KEY_READ | DELETE,
503 &hKey);
505 if (ERROR_SUCCESS == rc)
507 wchar_t* lpSubKey;
508 DWORD nMaxSubKeyLen;
510 rc = RegQueryInfoKeyW(
511 hKey, 0, 0, 0, 0,
512 &nMaxSubKeyLen,
513 0, 0, 0, 0, 0, 0);
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;
524 rc = RegEnumKeyExW(
525 hKey,
526 0, // always index zero
527 lpSubKey,
528 &nLen,
529 0, 0, 0, 0);
531 if (ERROR_NO_MORE_ITEMS == rc)
533 rc = RegDeleteKeyW(RootKey, Name.c_str());
534 break;
536 else if (rc == ERROR_SUCCESS)
538 rc = ImplDeleteSubKeyTree(hKey, lpSubKey);
541 } // while
543 RegCloseKey(hKey);
545 } // if
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);
556 return rc;
559 //-----------------------------------------------------
560 /** Delete the specified value
562 @precond IsOpen = true
563 IsWriteable = true
564 HasValue(Name) = true
566 @throws RegistryIOException
567 RegistryWriteAccessDeniedException
568 RegistryValueNotFoundException
570 void RegistryKeyImplWinNT::DeleteValue(const std::wstring& Name)
572 assert(IsOpen());
573 assert(HasValue(Name));
574 assert(IsWriteable());
576 LONG rc = RegDeleteValueW(
577 m_hSubKey,
578 Name.c_str());
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
594 IsWriteable = true
596 @throws RegistryIOException
597 RegistryWriteAccessDenyException
599 void RegistryKeyImplWinNT::SetValue(const RegistryValue& Value)
601 assert(IsOpen());
602 assert(IsWriteable());
604 LONG rc = RegSetValueExW(
605 m_hSubKey,
606 Value->GetName().c_str(),
608 Value->GetType(),
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);