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"
33 #include "registryvalueimpl.hxx"
34 #include "registryexception.hxx"
35 #include "stringconverter.hxx"
40 #pragma warning(disable : 4786 4350)
43 const size_t MAX_TMP_BUFF_SIZE
= 1024 * sizeof(wchar_t);
46 //############################################
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 //############################################
80 //############################################
83 //-----------------------------------------------------
84 /** The number of sub values of the key at hand
86 @precond IsOpen = true
90 size_t RegistryKeyImplWin9x::GetSubValueCount() const
96 LONG rc
= RegQueryInfoKeyA(
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
);
108 //-----------------------------------------------------
109 /** The number of sub-keys of the key at hand
111 @precond IsOpen = true
115 size_t RegistryKeyImplWin9x::GetSubKeyCount() const
121 LONG rc
= RegQueryInfoKeyA(
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
);
133 StringListPtr
RegistryKeyImplWin9x::GetSubKeyNames() const
138 DWORD buff_size
= sizeof(buff
);
141 StringList
* key_names
= new StringList();
143 LONG rc
= ERROR_SUCCESS
;
145 for (DWORD i
= 0; /* left empty */; i
++)
148 m_hSubKey
, i
, buff
, &buff_size
,
151 if (ERROR_SUCCESS
!= rc
&&
152 ERROR_MORE_DATA
!= rc
)
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
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
++)
182 m_hSubKey
, i
, buff
, &buff_size
,
185 if (ERROR_SUCCESS
!= rc
&&
186 ERROR_MORE_DATA
!= rc
)
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
212 char buff
[MAX_TMP_BUFF_SIZE
];
213 DWORD size
= sizeof(buff
);
215 LONG rc
= RegQueryValueExA(
217 UnicodeToAnsiString(Name
).c_str(),
220 reinterpret_cast<LPBYTE
>(buff
),
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
)
239 regval
= RegistryValue(new RegistryValueImpl(Name
, std::string(reinterpret_cast<char*>(buff
))));
241 regval
= RegistryValue(new RegistryValueImpl(Name
, std::string()));
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
262 char buff
[MAX_TMP_BUFF_SIZE
];
263 DWORD size
= sizeof(buff
);
265 LONG rc
= RegQueryValueExA(
267 UnicodeToAnsiString(Name
).c_str(),
270 reinterpret_cast<LPBYTE
>(buff
),
273 if (ERROR_FILE_NOT_FOUND
== rc
)
275 #if !defined(__MINGW32__) && (_MSC_VER < 1300)
278 RegistryValue regval_ptr
;
279 regval_ptr
= RegistryValue(new RegistryValueImpl(*Default
));
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
))));
302 //############################################
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
)
321 REGSAM regsam
= KEY_READ
;
326 LONG rc
= RegOpenKeyExA(
328 UnicodeToAnsiString(m_KeyName
).c_str(),
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
;
345 //-----------------------------------------------------
346 /** Open the specified sub-key of the registry key
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
);
363 //-----------------------------------------------------
364 /** Creates a new sub-key below the key at hand
366 @precond IsOpen = true
369 @throws RegistryIOException
370 RegistryWriteAccessDenyException
373 RegistryKey
RegistryKeyImplWin9x::CreateSubKey(const std::wstring
& Name
)
376 assert(IsWriteable());
378 HKEY hRoot
= IsRootKey() ? m_hRootKey
: m_hSubKey
;
382 LONG rc
= RegCreateKeyExA(
384 UnicodeToAnsiString(Name
).c_str(),
387 REG_OPTION_NON_VOLATILE
,
388 KEY_READ
| KEY_WRITE
,
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
410 @throws RegistryIOException
411 RegistryWriteAccessDenyException
413 void RegistryKeyImplWin9x::DeleteSubKey(const std::wstring
& Name
)
416 assert(IsWriteable());
417 assert(HasSubKey(Name
));
419 RegistryKey SubKey
= OpenSubKey(Name
);
421 size_t nSubKeyCount
= SubKey
->GetSubKeyCount();
423 assert(0 == 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
442 @precond IsOpen = 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
465 HasValue(Name) = true
467 @throws RegistryIOException
468 RegistryWriteAccessDeniedException
469 RegistryValueNotFoundException
471 void RegistryKeyImplWin9x::DeleteValue(const std::wstring
& Name
)
474 assert(HasValue(Name
));
475 assert(IsWriteable());
477 LONG rc
= RegDeleteValueA(
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
497 @throws RegistryIOException
498 RegistryWriteAccessDenyException
500 void RegistryKeyImplWin9x::SetValue(const RegistryValue
& Value
)
503 assert(IsWriteable());
505 LONG rc
= ERROR_SUCCESS
;
507 if (REG_SZ
== Value
->GetType())
509 std::string AnsiStr
= Value
->GetDataAsAnsiString();
513 UnicodeToAnsiString(Value
->GetName()).c_str(),
516 reinterpret_cast<const unsigned char*>(AnsiStr
.c_str()),
517 static_cast<DWORD
>((AnsiStr
.length() + 1)));
523 UnicodeToAnsiString(Value
->GetName()).c_str(),
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: */