Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / setup_native / source / win32 / customactions / reg4msdoc / registryw9x.cxx
blob30e1cf07c5b50143b1e69d54393f8dfae7afb536
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 #include "registryw9x.hxx"
31 #include <windows.h>
32 #include <malloc.h>
33 #include "registryvalueimpl.hxx"
34 #include "registryexception.hxx"
35 #include "stringconverter.hxx"
37 #include <assert.h>
39 #ifdef _MSC_VER
40 #pragma warning(disable : 4786 4350)
41 #endif
43 const size_t MAX_TMP_BUFF_SIZE = 1024 * sizeof(wchar_t);
46 //############################################
47 // Creation
48 // only possible through WindowsRegistry class
49 //############################################
52 //-----------------------------------------------------
53 /** Create instance and open the specified Registry key
55 RegistryKeyImplWin9x::RegistryKeyImplWin9x(HKEY RootKey, const std::wstring& KeyName) :
56 RegistryKeyImpl(RootKey, KeyName)
60 //-----------------------------------------------------
61 /** Create instance and open the specified Registry key
63 RegistryKeyImplWin9x::RegistryKeyImplWin9x(HKEY RootKey) :
64 RegistryKeyImpl(RootKey)
68 //-----------------------------------------------------
69 /** Create an instances of the specified Registry key,
70 the key is assumed to be already opened.
72 RegistryKeyImplWin9x::RegistryKeyImplWin9x(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable) :
73 RegistryKeyImpl(RootKey, SubKey, KeyName, Writeable)
78 //############################################
79 // Queries
80 //############################################
83 //-----------------------------------------------------
84 /** The number of sub values of the key at hand
86 @precond IsOpen = true
88 @throws
90 size_t RegistryKeyImplWin9x::GetSubValueCount() const
92 assert(IsOpen());
94 DWORD nSubValues = 0;
96 LONG rc = RegQueryInfoKeyA(
97 m_hSubKey,
98 0, 0, 0, 0, 0, 0, &nSubValues, 0, 0, 0, 0);
100 if (ERROR_INVALID_HANDLE == rc)
101 throw RegistryIOException(rc);
102 else if (ERROR_SUCCESS != rc)
103 throw RegistryException(rc);
105 return nSubValues;
108 //-----------------------------------------------------
109 /** The number of sub-keys of the key at hand
111 @precond IsOpen = true
113 @throws
115 size_t RegistryKeyImplWin9x::GetSubKeyCount() const
117 assert(IsOpen());
119 DWORD nSubKeys = 0;
121 LONG rc = RegQueryInfoKeyA(
122 m_hSubKey,
123 0, 0, 0, &nSubKeys, 0, 0, 0, 0, 0, 0, 0);
125 if (ERROR_INVALID_HANDLE == rc)
126 throw RegistryIOException(rc);
127 else if (ERROR_SUCCESS != rc)
128 throw RegistryException(rc);
130 return nSubKeys;
133 StringListPtr RegistryKeyImplWin9x::GetSubKeyNames() const
135 assert(IsOpen());
137 char buff[1024];
138 DWORD buff_size = sizeof(buff);
139 FILETIME ftime;
141 StringList* key_names = new StringList();
143 LONG rc = ERROR_SUCCESS;
145 for (DWORD i = 0; /* left empty */; i++)
147 rc = RegEnumKeyExA(
148 m_hSubKey, i, buff, &buff_size,
149 0, 0, 0, &ftime);
151 if (ERROR_SUCCESS != rc &&
152 ERROR_MORE_DATA != rc)
153 break;
155 buff_size = sizeof(buff);
157 key_names->push_back(AnsiToUnicodeString(buff));
160 if (ERROR_INVALID_HANDLE == rc)
161 throw RegistryIOException(rc);
162 else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
163 throw RegistryException(rc);
165 return (StringListPtr) key_names;
168 StringListPtr RegistryKeyImplWin9x::GetSubValueNames() const
170 assert(IsOpen());
172 char buff[1024];
173 DWORD buff_size = sizeof(buff);
175 StringList* value_names = new StringList();
177 LONG rc = ERROR_SUCCESS;
179 for (DWORD i = 0; /* left empty */; i++)
181 rc = RegEnumValueA(
182 m_hSubKey, i, buff, &buff_size,
183 0, 0, 0, 0);
185 if (ERROR_SUCCESS != rc &&
186 ERROR_MORE_DATA != rc)
187 break;
189 buff_size = sizeof(buff);
191 value_names->push_back(AnsiToUnicodeString(buff));
194 if (ERROR_INVALID_HANDLE == rc)
195 throw RegistryIOException(rc);
196 else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
197 throw RegistryException(rc);
199 return (StringListPtr) value_names;
202 //-----------------------------------------------------
203 /** Get the specified registry value
205 @precond IsOpen = true
207 RegistryValue RegistryKeyImplWin9x::GetValue(const std::wstring& Name) const
209 assert(IsOpen());
211 DWORD Type;
212 char buff[MAX_TMP_BUFF_SIZE];
213 DWORD size = sizeof(buff);
215 LONG rc = RegQueryValueExA(
216 m_hSubKey,
217 UnicodeToAnsiString(Name).c_str(),
219 &Type,
220 reinterpret_cast<LPBYTE>(buff),
221 &size);
223 if (ERROR_FILE_NOT_FOUND == rc)
224 throw RegistryValueNotFoundException(rc);
225 else if (ERROR_ACCESS_DENIED == rc)
226 throw RegistryAccessDeniedException(rc);
227 else if (ERROR_SUCCESS != rc)
228 throw RegistryException(rc);
230 RegistryValue regval;
232 if (REG_DWORD == Type)
234 regval = RegistryValue(new RegistryValueImpl(Name, *(reinterpret_cast<int*>(buff))));
236 else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
238 if (size > 0)
239 regval = RegistryValue(new RegistryValueImpl(Name, std::string(reinterpret_cast<char*>(buff))));
240 else
241 regval = RegistryValue(new RegistryValueImpl(Name, std::string()));
243 else
245 assert(false);
248 return regval;
251 //-----------------------------------------------------
252 /** Get the specified registry value, return the given
253 default value if value not found
255 @precond IsOpen = true
257 RegistryValue RegistryKeyImplWin9x::GetValue(const std::wstring& Name, const RegistryValue& Default) const
259 assert(IsOpen());
261 DWORD Type;
262 char buff[MAX_TMP_BUFF_SIZE];
263 DWORD size = sizeof(buff);
265 LONG rc = RegQueryValueExA(
266 m_hSubKey,
267 UnicodeToAnsiString(Name).c_str(),
269 &Type,
270 reinterpret_cast<LPBYTE>(buff),
271 &size);
273 if (ERROR_FILE_NOT_FOUND == rc)
275 #if !defined(__MINGW32__) && (_MSC_VER < 1300)
276 return Default;
277 #else
278 RegistryValue regval_ptr;
279 regval_ptr = RegistryValue(new RegistryValueImpl(*Default));
280 return regval_ptr;
281 #endif
284 if (ERROR_ACCESS_DENIED == rc)
285 throw RegistryAccessDeniedException(rc);
286 else if (ERROR_SUCCESS != rc)
287 throw RegistryException(rc);
289 RegistryValue regval;
291 if (REG_DWORD == Type)
292 regval = RegistryValue(new RegistryValueImpl(Name, *reinterpret_cast<int*>(buff)));
293 else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
294 regval = RegistryValue(new RegistryValueImpl(Name, std::string(reinterpret_cast<char*>(buff))));
295 else
296 assert(false);
298 return regval;
302 //############################################
303 // Commands
304 //############################################
307 //-----------------------------------------------------
308 /** Open the registry key, has no effect if
309 the key is already open
311 @precond IsOpen = false
313 @throws RegistryKeyNotFoundException
314 RegistryWriteAccessDenyException
315 RegistryAccessDenyException
317 void RegistryKeyImplWin9x::Open(bool Writeable)
319 assert(!IsOpen());
321 REGSAM regsam = KEY_READ;
323 if (Writeable)
324 regsam |= KEY_WRITE;
326 LONG rc = RegOpenKeyExA(
327 m_hRootKey,
328 UnicodeToAnsiString(m_KeyName).c_str(),
330 regsam,
331 &m_hSubKey);
333 if (ERROR_FILE_NOT_FOUND == rc)
334 throw RegistryKeyNotFoundException(rc);
335 else if (ERROR_ACCESS_DENIED == rc)
336 throw RegistryAccessDeniedException(rc);
337 else if (ERROR_SUCCESS != rc)
338 throw RegistryException(rc);
340 m_IsWriteable = Writeable;
342 assert(IsOpen());
345 //-----------------------------------------------------
346 /** Open the specified sub-key of the registry key
347 at hand
349 @precond IsOpen = true
350 HasSubKey(Name) = true
352 @throws RegistryIOException
353 RegistryKeyNotFoundException
354 RegistryAccessDeniedException
356 RegistryKey RegistryKeyImplWin9x::OpenSubKey(const std::wstring& Name, bool Writeable)
358 RegistryKey regkey(new RegistryKeyImplWin9x(m_hSubKey, Name));
359 regkey->Open(Writeable);
360 return regkey;
363 //-----------------------------------------------------
364 /** Creates a new sub-key below the key at hand
366 @precond IsOpen = true
367 IsWriteable = true
369 @throws RegistryIOException
370 RegistryWriteAccessDenyException
373 RegistryKey RegistryKeyImplWin9x::CreateSubKey(const std::wstring& Name)
375 assert(IsOpen());
376 assert(IsWriteable());
378 HKEY hRoot = IsRootKey() ? m_hRootKey : m_hSubKey;
380 HKEY hKey;
382 LONG rc = RegCreateKeyExA(
383 hRoot,
384 UnicodeToAnsiString(Name).c_str(),
387 REG_OPTION_NON_VOLATILE,
388 KEY_READ | KEY_WRITE,
390 &hKey,
393 if (ERROR_INVALID_HANDLE == rc)
394 throw RegistryIOException(rc);
395 else if (ERROR_ACCESS_DENIED == rc)
396 throw RegistryAccessDeniedException(rc);
397 else if (ERROR_SUCCESS != rc)
398 throw RegistryException(rc);
400 return RegistryKey(new RegistryKeyImplWin9x(hRoot, hKey, Name));
403 //-----------------------------------------------------
404 /** Deletes a sub-key below the key at hand, the
405 key must not have sub-keys
407 @precond IsOpen = true
408 IsWriteable = true
410 @throws RegistryIOException
411 RegistryWriteAccessDenyException
413 void RegistryKeyImplWin9x::DeleteSubKey(const std::wstring& Name)
415 assert(IsOpen());
416 assert(IsWriteable());
417 assert(HasSubKey(Name));
419 RegistryKey SubKey = OpenSubKey(Name);
421 size_t nSubKeyCount = SubKey->GetSubKeyCount();
423 assert(0 == nSubKeyCount);
425 if (nSubKeyCount)
426 throw RegistryInvalidOperationException(ERROR_NOT_SUPPORTED);
428 LONG rc = RegDeleteKeyA(m_hSubKey, UnicodeToAnsiString(Name).c_str());
430 if (ERROR_INVALID_HANDLE == rc)
431 throw RegistryIOException(rc);
432 else if (ERROR_ACCESS_DENIED == rc)
433 throw RegistryAccessDeniedException(rc);
434 else if (ERROR_SUCCESS != rc)
435 throw RegistryException(rc);
438 //-----------------------------------------------------
439 /** Deletes a sub-key below the key at hand with all
440 its sub-keys
442 @precond IsOpen = true
443 IsWriteable = true;
445 @throws RegistryIOException
446 RegistryWriteAccessDenyException
448 void RegistryKeyImplWin9x::DeleteSubKeyTree(const std::wstring& Name)
450 LONG rc = RegDeleteKeyA(m_hSubKey, UnicodeToAnsiString(Name).c_str());
452 if (ERROR_INVALID_HANDLE == rc)
453 throw RegistryIOException(rc);
454 else if (ERROR_ACCESS_DENIED == rc)
455 throw RegistryAccessDeniedException(rc);
456 else if (ERROR_SUCCESS != rc)
457 throw RegistryException(rc);
460 //-----------------------------------------------------
461 /** Delete the specified value
463 @precond IsOpen = true
464 IsWriteable = true
465 HasValue(Name) = true
467 @throws RegistryIOException
468 RegistryWriteAccessDeniedException
469 RegistryValueNotFoundException
471 void RegistryKeyImplWin9x::DeleteValue(const std::wstring& Name)
473 assert(IsOpen());
474 assert(HasValue(Name));
475 assert(IsWriteable());
477 LONG rc = RegDeleteValueA(
478 m_hSubKey,
479 UnicodeToAnsiString(Name).c_str());
481 if (ERROR_INVALID_HANDLE == rc)
482 throw RegistryIOException(rc);
483 else if (ERROR_ACCESS_DENIED == rc)
484 throw RegistryNoWriteAccessException(rc);
485 else if (ERROR_FILE_NOT_FOUND == rc)
486 throw RegistryValueNotFoundException(rc);
487 else if (ERROR_SUCCESS != rc)
488 throw RegistryException(rc);
491 //-----------------------------------------------------
492 /** Set the specified registry value
494 @precond IsOpen = true
495 IsWriteable = true
497 @throws RegistryIOException
498 RegistryWriteAccessDenyException
500 void RegistryKeyImplWin9x::SetValue(const RegistryValue& Value)
502 assert(IsOpen());
503 assert(IsWriteable());
505 LONG rc = ERROR_SUCCESS;
507 if (REG_SZ == Value->GetType())
509 std::string AnsiStr = Value->GetDataAsAnsiString();
511 rc = RegSetValueExA(
512 m_hSubKey,
513 UnicodeToAnsiString(Value->GetName()).c_str(),
515 Value->GetType(),
516 reinterpret_cast<const unsigned char*>(AnsiStr.c_str()),
517 static_cast<DWORD>((AnsiStr.length() + 1)));
519 else
521 rc = RegSetValueExA(
522 m_hSubKey,
523 UnicodeToAnsiString(Value->GetName()).c_str(),
525 Value->GetType(),
526 reinterpret_cast<const unsigned char*>(Value->GetDataBuffer()),
527 static_cast<DWORD>(Value->GetDataSize()));
530 if (ERROR_INVALID_HANDLE == rc)
531 throw RegistryIOException(rc);
532 else if (ERROR_ACCESS_DENIED == rc)
533 throw RegistryAccessDeniedException(rc);
534 else if (ERROR_SUCCESS != rc)
535 throw RegistryException(rc);
538 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */