1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir //---------------------------------------
29*cdf0e10cSrcweir //
30*cdf0e10cSrcweir //---------------------------------------
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #ifdef _MSC_VER
33*cdf0e10cSrcweir #pragma warning(push, 1) /* disable warnings within system headers */
34*cdf0e10cSrcweir #endif
35*cdf0e10cSrcweir #include <windows.h>
36*cdf0e10cSrcweir #ifdef _MSC_VER
37*cdf0e10cSrcweir #pragma warning(pop)
38*cdf0e10cSrcweir #endif
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir #include <malloc.h>
41*cdf0e10cSrcweir #include "registrywnt.hxx"
42*cdf0e10cSrcweir #include "registryvalueimpl.hxx"
43*cdf0e10cSrcweir #include "registryexception.hxx"
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #include <assert.h>
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir #ifdef _MSC_VER
48*cdf0e10cSrcweir #pragma warning(disable : 4786 4350)
49*cdf0e10cSrcweir #endif
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir //---------------------------------------
52*cdf0e10cSrcweir //
53*cdf0e10cSrcweir //---------------------------------------
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir const size_t MAX_TMP_BUFF_SIZE = 1024 * sizeof(wchar_t);
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir //############################################
59*cdf0e10cSrcweir // Creation
60*cdf0e10cSrcweir // only possible through WindowsRegistry class
61*cdf0e10cSrcweir //############################################
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir //-----------------------------------------------------
65*cdf0e10cSrcweir /** Create instance and open the specified Registry key
66*cdf0e10cSrcweir */
67*cdf0e10cSrcweir RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey, const std::wstring& KeyName) :
68*cdf0e10cSrcweir 	RegistryKeyImpl(RootKey, KeyName)
69*cdf0e10cSrcweir {
70*cdf0e10cSrcweir }
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir //-----------------------------------------------------
73*cdf0e10cSrcweir /** Create instance and open the specified Registry key
74*cdf0e10cSrcweir */
75*cdf0e10cSrcweir RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey) :
76*cdf0e10cSrcweir 	RegistryKeyImpl(RootKey)
77*cdf0e10cSrcweir {
78*cdf0e10cSrcweir }
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir //-----------------------------------------------------
81*cdf0e10cSrcweir /** Create an instances of the specified Registry key,
82*cdf0e10cSrcweir 	the key is assumed to be already opened.
83*cdf0e10cSrcweir */
84*cdf0e10cSrcweir RegistryKeyImplWinNT::RegistryKeyImplWinNT(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable) :
85*cdf0e10cSrcweir 	RegistryKeyImpl(RootKey, SubKey, KeyName, Writeable)
86*cdf0e10cSrcweir {
87*cdf0e10cSrcweir }
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir //############################################
91*cdf0e10cSrcweir // Queries
92*cdf0e10cSrcweir //############################################
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir //-----------------------------------------------------
96*cdf0e10cSrcweir /** The number of sub values of the key at hand
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir 	@precond IsOpen = true
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir 	@throws
101*cdf0e10cSrcweir */
102*cdf0e10cSrcweir size_t RegistryKeyImplWinNT::GetSubValueCount() const
103*cdf0e10cSrcweir {
104*cdf0e10cSrcweir 	assert(IsOpen());
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir 	DWORD nSubValues = 0;
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir 	LONG rc = RegQueryInfoKeyW(
109*cdf0e10cSrcweir 		m_hSubKey,
110*cdf0e10cSrcweir 		0, 0, 0, 0, 0, 0, &nSubValues, 0, 0, 0, 0);
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
113*cdf0e10cSrcweir 		throw RegistryIOException(rc);
114*cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
115*cdf0e10cSrcweir 		throw RegistryException(rc);
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir 	return nSubValues;
118*cdf0e10cSrcweir }
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir //-----------------------------------------------------
121*cdf0e10cSrcweir /** The number of sub-keys of the key at hand
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir 	@precond IsOpen = true
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir 	@throws
126*cdf0e10cSrcweir */
127*cdf0e10cSrcweir size_t RegistryKeyImplWinNT::GetSubKeyCount() const
128*cdf0e10cSrcweir {
129*cdf0e10cSrcweir 	assert(IsOpen());
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir 	DWORD nSubKeys = 0;
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir 	LONG rc = RegQueryInfoKeyA(
134*cdf0e10cSrcweir 		m_hSubKey,
135*cdf0e10cSrcweir 		0, 0, 0, &nSubKeys, 0, 0, 0, 0, 0, 0, 0);
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
138*cdf0e10cSrcweir 		throw RegistryIOException(rc);
139*cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
140*cdf0e10cSrcweir 		throw RegistryException(rc);
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir 	return nSubKeys;
143*cdf0e10cSrcweir }
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir //-----------------------------------------------------
146*cdf0e10cSrcweir /**
147*cdf0e10cSrcweir */
148*cdf0e10cSrcweir StringListPtr RegistryKeyImplWinNT::GetSubKeyNames() const
149*cdf0e10cSrcweir {
150*cdf0e10cSrcweir 	assert(IsOpen());
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir 	wchar_t buff[1024];
153*cdf0e10cSrcweir 	DWORD  buff_size = sizeof(buff);
154*cdf0e10cSrcweir 	FILETIME ftime;
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir 	StringList* key_names = new StringList();
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir 	LONG rc = ERROR_SUCCESS;
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir 	for (DWORD i = 0; /* left empty */; i++)
161*cdf0e10cSrcweir 	{
162*cdf0e10cSrcweir 		rc = RegEnumKeyExW(
163*cdf0e10cSrcweir 			m_hSubKey, i, buff, &buff_size,
164*cdf0e10cSrcweir 			0, 0, 0, &ftime);
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir 		if (ERROR_SUCCESS != rc &&
167*cdf0e10cSrcweir 			ERROR_MORE_DATA != rc)
168*cdf0e10cSrcweir 			break;
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir 		buff_size = sizeof(buff);
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir 		key_names->push_back(buff);
173*cdf0e10cSrcweir 	}
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
176*cdf0e10cSrcweir 		throw RegistryIOException(rc);
177*cdf0e10cSrcweir 	else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
178*cdf0e10cSrcweir 		throw RegistryException(rc);
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir #if (_MSC_VER < 1300) && !defined(__MINGW32__)
181*cdf0e10cSrcweir 	return key_names;
182*cdf0e10cSrcweir #else
183*cdf0e10cSrcweir 	return (StringListPtr) key_names;
184*cdf0e10cSrcweir #endif
185*cdf0e10cSrcweir }
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir //-----------------------------------------------------
188*cdf0e10cSrcweir /**
189*cdf0e10cSrcweir */
190*cdf0e10cSrcweir StringListPtr RegistryKeyImplWinNT::GetSubValueNames() const
191*cdf0e10cSrcweir {
192*cdf0e10cSrcweir 	assert(IsOpen());
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 	wchar_t buff[1024];
195*cdf0e10cSrcweir 	DWORD  buff_size = sizeof(buff);
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir 	StringList* value_names = new StringList();
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir 	LONG rc = ERROR_SUCCESS;
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir 	for (DWORD i = 0; /* left empty */; i++)
202*cdf0e10cSrcweir 	{
203*cdf0e10cSrcweir 		rc = RegEnumValueW(
204*cdf0e10cSrcweir 			m_hSubKey, i, buff, &buff_size,
205*cdf0e10cSrcweir 			0, 0, 0, 0);
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir 		if (ERROR_SUCCESS != rc &&
208*cdf0e10cSrcweir 			ERROR_MORE_DATA != rc)
209*cdf0e10cSrcweir 			break;
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir 		buff_size = sizeof(buff);
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir 		value_names->push_back(buff);
214*cdf0e10cSrcweir 	}
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
217*cdf0e10cSrcweir 		throw RegistryIOException(rc);
218*cdf0e10cSrcweir 	else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
219*cdf0e10cSrcweir 		throw RegistryException(rc);
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir #if (_MSC_VER < 1300) && !defined(__MINGW32__)
222*cdf0e10cSrcweir 	return value_names;
223*cdf0e10cSrcweir #else
224*cdf0e10cSrcweir 	return (StringListPtr) value_names;
225*cdf0e10cSrcweir #endif
226*cdf0e10cSrcweir }
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir //-----------------------------------------------------
229*cdf0e10cSrcweir /** Get the specified registry value
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir 	@precond IsOpen = true
232*cdf0e10cSrcweir */
233*cdf0e10cSrcweir RegistryValue RegistryKeyImplWinNT::GetValue(const std::wstring& Name) const
234*cdf0e10cSrcweir {
235*cdf0e10cSrcweir 	assert(IsOpen());
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir 	DWORD Type;
238*cdf0e10cSrcweir 	wchar_t buff[MAX_TMP_BUFF_SIZE];
239*cdf0e10cSrcweir 	DWORD   size = sizeof(buff);
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir 	LONG rc = RegQueryValueExW(
242*cdf0e10cSrcweir 		m_hSubKey,
243*cdf0e10cSrcweir 		Name.c_str(),
244*cdf0e10cSrcweir 		0,
245*cdf0e10cSrcweir 		&Type,
246*cdf0e10cSrcweir 		reinterpret_cast<LPBYTE>(buff),
247*cdf0e10cSrcweir 		&size);
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir 	if (ERROR_FILE_NOT_FOUND == rc)
250*cdf0e10cSrcweir 		throw RegistryValueNotFoundException(rc);
251*cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
252*cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
253*cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
254*cdf0e10cSrcweir 		throw RegistryException(rc);
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir 	RegistryValue regval;
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir 	if (REG_DWORD == Type)
259*cdf0e10cSrcweir     {
260*cdf0e10cSrcweir 		regval = RegistryValue(new RegistryValueImpl(Name, *(reinterpret_cast<int*>(buff))));
261*cdf0e10cSrcweir     }
262*cdf0e10cSrcweir 	else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
263*cdf0e10cSrcweir     {
264*cdf0e10cSrcweir         if (size > 0)
265*cdf0e10cSrcweir             regval = RegistryValue(new RegistryValueImpl(Name, std::wstring(reinterpret_cast<wchar_t*>(buff))));
266*cdf0e10cSrcweir         else
267*cdf0e10cSrcweir             regval = RegistryValue(new RegistryValueImpl(Name, std::wstring()));
268*cdf0e10cSrcweir     }
269*cdf0e10cSrcweir 	else
270*cdf0e10cSrcweir     {
271*cdf0e10cSrcweir 		assert(false);
272*cdf0e10cSrcweir     }
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir 	return regval;
275*cdf0e10cSrcweir }
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir //-----------------------------------------------------
278*cdf0e10cSrcweir /** Get the specified registry value, return the given
279*cdf0e10cSrcweir 	default value if value not found
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir 	@precond IsOpen = true
282*cdf0e10cSrcweir */
283*cdf0e10cSrcweir RegistryValue RegistryKeyImplWinNT::GetValue(const std::wstring& Name, const RegistryValue& Default) const
284*cdf0e10cSrcweir {
285*cdf0e10cSrcweir 	assert(IsOpen());
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir 	DWORD Type;
288*cdf0e10cSrcweir 	wchar_t buff[MAX_TMP_BUFF_SIZE];
289*cdf0e10cSrcweir 	DWORD   size = sizeof(buff);
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir 	LONG rc = RegQueryValueExW(
292*cdf0e10cSrcweir 		m_hSubKey,
293*cdf0e10cSrcweir 		Name.c_str(),
294*cdf0e10cSrcweir 		0,
295*cdf0e10cSrcweir 		&Type,
296*cdf0e10cSrcweir 		reinterpret_cast<LPBYTE>(buff),
297*cdf0e10cSrcweir 		&size);
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir 	if (ERROR_FILE_NOT_FOUND == rc)
300*cdf0e10cSrcweir 	{
301*cdf0e10cSrcweir 		#if (_MSC_VER < 1300) && !defined(__MINGW32__)
302*cdf0e10cSrcweir 		return Default;
303*cdf0e10cSrcweir 		#else
304*cdf0e10cSrcweir 		RegistryValue regval_ptr;
305*cdf0e10cSrcweir 		regval_ptr = RegistryValue(new RegistryValueImpl(*Default));
306*cdf0e10cSrcweir 		return regval_ptr;
307*cdf0e10cSrcweir 		#endif
308*cdf0e10cSrcweir 	}
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir 	if (ERROR_ACCESS_DENIED == rc)
311*cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
312*cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
313*cdf0e10cSrcweir 		throw RegistryException(rc);
314*cdf0e10cSrcweir 
315*cdf0e10cSrcweir 	RegistryValue regval;
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir 	if (REG_DWORD == Type)
318*cdf0e10cSrcweir 		regval = RegistryValue(new RegistryValueImpl(Name, *reinterpret_cast<int*>(buff)));
319*cdf0e10cSrcweir 	else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
320*cdf0e10cSrcweir 		regval = RegistryValue(new RegistryValueImpl(Name, std::wstring(reinterpret_cast<wchar_t*>(buff))));
321*cdf0e10cSrcweir 	else
322*cdf0e10cSrcweir 		assert(false);
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir 	return regval;
325*cdf0e10cSrcweir }
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir //############################################
329*cdf0e10cSrcweir // Commands
330*cdf0e10cSrcweir //############################################
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir //-----------------------------------------------------
334*cdf0e10cSrcweir /** Open the registry key, has no effect if
335*cdf0e10cSrcweir 	the key is already open
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir 	@precond IsOpen = false
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir 	@throws RegistryKeyNotFoundException
340*cdf0e10cSrcweir 			RegistryWriteAccessDenyException
341*cdf0e10cSrcweir 			RegistryAccessDenyException
342*cdf0e10cSrcweir */
343*cdf0e10cSrcweir void RegistryKeyImplWinNT::Open(bool Writeable)
344*cdf0e10cSrcweir {
345*cdf0e10cSrcweir 	assert(!IsOpen());
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir 	REGSAM regsam = KEY_READ;
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir 	if (Writeable)
350*cdf0e10cSrcweir 		regsam |= KEY_WRITE;
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir 	LONG rc = RegOpenKeyExW(
353*cdf0e10cSrcweir 		m_hRootKey,
354*cdf0e10cSrcweir 		m_KeyName.c_str(),
355*cdf0e10cSrcweir 		0,
356*cdf0e10cSrcweir 		regsam,
357*cdf0e10cSrcweir 		&m_hSubKey);
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir 	if (ERROR_FILE_NOT_FOUND == rc)
360*cdf0e10cSrcweir 		throw RegistryKeyNotFoundException(rc);
361*cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
362*cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
363*cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
364*cdf0e10cSrcweir 		throw RegistryException(rc);
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir 	m_IsWriteable = Writeable;
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir 	assert(IsOpen());
369*cdf0e10cSrcweir }
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir //-----------------------------------------------------
372*cdf0e10cSrcweir /** Open the specified sub-key of the registry key
373*cdf0e10cSrcweir 	at hand
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir 	@precond IsOpen = true
376*cdf0e10cSrcweir 			 HasSubKey(Name) = true
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir 	@throws RegistryIOException
379*cdf0e10cSrcweir 			RegistryKeyNotFoundException
380*cdf0e10cSrcweir 			RegistryAccessDeniedException
381*cdf0e10cSrcweir */
382*cdf0e10cSrcweir RegistryKey RegistryKeyImplWinNT::OpenSubKey(const std::wstring& Name, bool Writeable)
383*cdf0e10cSrcweir {
384*cdf0e10cSrcweir 	RegistryKey regkey(new RegistryKeyImplWinNT(m_hSubKey, Name));
385*cdf0e10cSrcweir 	regkey->Open(Writeable);
386*cdf0e10cSrcweir 	return regkey;
387*cdf0e10cSrcweir }
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir //-----------------------------------------------------
390*cdf0e10cSrcweir /** Creates a new sub-key below the key at hand
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir 	@precond IsOpen = true
393*cdf0e10cSrcweir 			 IsWriteable = true
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir 	@throws  RegistryIOException
396*cdf0e10cSrcweir 			 RegistryWriteAccessDenyException
397*cdf0e10cSrcweir */
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir RegistryKey RegistryKeyImplWinNT::CreateSubKey(const std::wstring& Name)
400*cdf0e10cSrcweir {
401*cdf0e10cSrcweir 	assert(IsOpen());
402*cdf0e10cSrcweir 	assert(IsWriteable());
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir 	HKEY hRoot = IsRootKey() ? m_hRootKey : m_hSubKey;
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir 	HKEY hKey;
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir 	LONG rc = RegCreateKeyExW(
409*cdf0e10cSrcweir 		hRoot,
410*cdf0e10cSrcweir 		Name.c_str(),
411*cdf0e10cSrcweir 		0,
412*cdf0e10cSrcweir 		0,
413*cdf0e10cSrcweir 		REG_OPTION_NON_VOLATILE,
414*cdf0e10cSrcweir 		KEY_READ | KEY_WRITE,
415*cdf0e10cSrcweir 		0,
416*cdf0e10cSrcweir 		&hKey,
417*cdf0e10cSrcweir 		0);
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
420*cdf0e10cSrcweir 		throw RegistryIOException(rc);
421*cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
422*cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
423*cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
424*cdf0e10cSrcweir 		throw RegistryException(rc);
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir 	return RegistryKey(new RegistryKeyImplWinNT(hRoot, hKey, Name));
427*cdf0e10cSrcweir }
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir //-----------------------------------------------------
430*cdf0e10cSrcweir /** Deletes a sub-key below the key at hand, the
431*cdf0e10cSrcweir 	key must not have sub-keys
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir 	@precond IsOpen = true
434*cdf0e10cSrcweir 			 IsWriteable = true
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir 	@throws  RegistryIOException
437*cdf0e10cSrcweir 			 RegistryWriteAccessDenyException
438*cdf0e10cSrcweir */
439*cdf0e10cSrcweir void RegistryKeyImplWinNT::DeleteSubKey(const std::wstring& Name)
440*cdf0e10cSrcweir {
441*cdf0e10cSrcweir 	assert(IsOpen());
442*cdf0e10cSrcweir 	assert(IsWriteable());
443*cdf0e10cSrcweir 	assert(HasSubKey(Name));
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir 	RegistryKey SubKey = OpenSubKey(Name);
446*cdf0e10cSrcweir 
447*cdf0e10cSrcweir 	size_t nSubKeyCount = SubKey->GetSubKeyCount();
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir 	assert(0 == nSubKeyCount);
450*cdf0e10cSrcweir 
451*cdf0e10cSrcweir 	if (nSubKeyCount)
452*cdf0e10cSrcweir 		throw RegistryInvalidOperationException(ERROR_NOT_SUPPORTED);
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir 	LONG rc = RegDeleteKeyW(m_hSubKey, Name.c_str());
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
457*cdf0e10cSrcweir 		throw RegistryIOException(rc);
458*cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
459*cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
460*cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
461*cdf0e10cSrcweir 		throw RegistryException(rc);
462*cdf0e10cSrcweir }
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir //-----------------------------------------------------
465*cdf0e10cSrcweir /** Deletes a sub-key below the key at hand with all
466*cdf0e10cSrcweir 	its sub-keys
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir 	@precond IsOpen = true
469*cdf0e10cSrcweir 			 IsWriteable = true;
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir 	@throws  RegistryIOException
472*cdf0e10cSrcweir 			 RegistryWriteAccessDenyException
473*cdf0e10cSrcweir */
474*cdf0e10cSrcweir void RegistryKeyImplWinNT::DeleteSubKeyTree(const std::wstring& Name)
475*cdf0e10cSrcweir {
476*cdf0e10cSrcweir 	ImplDeleteSubKeyTree(m_hSubKey, Name);
477*cdf0e10cSrcweir }
478*cdf0e10cSrcweir 
479*cdf0e10cSrcweir //-----------------------------------------------------
480*cdf0e10cSrcweir /** Deletes a sub-key below the key at hand with all
481*cdf0e10cSrcweir 	its sub-keys
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir 	@precond IsOpen = true
484*cdf0e10cSrcweir 			 IsWriteable = true;
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir 	@throws  RegistryIOException
487*cdf0e10cSrcweir 			 RegistryWriteAccessDenyException
488*cdf0e10cSrcweir */
489*cdf0e10cSrcweir LONG RegistryKeyImplWinNT::ImplDeleteSubKeyTree(HKEY RootKey, const std::wstring& Name)
490*cdf0e10cSrcweir {
491*cdf0e10cSrcweir 	assert(IsOpen());
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir 	HKEY hKey;
494*cdf0e10cSrcweir 
495*cdf0e10cSrcweir 	LONG rc = RegOpenKeyExW(
496*cdf0e10cSrcweir 		RootKey,
497*cdf0e10cSrcweir 		Name.c_str(),
498*cdf0e10cSrcweir 		0,
499*cdf0e10cSrcweir 		KEY_READ | DELETE,
500*cdf0e10cSrcweir 		&hKey);
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir 	if (ERROR_SUCCESS == rc)
503*cdf0e10cSrcweir 	{
504*cdf0e10cSrcweir 		wchar_t* lpSubKey;
505*cdf0e10cSrcweir 		DWORD    nMaxSubKeyLen;
506*cdf0e10cSrcweir 
507*cdf0e10cSrcweir 		rc = RegQueryInfoKeyW(
508*cdf0e10cSrcweir 			hKey, 0, 0, 0, 0,
509*cdf0e10cSrcweir 			&nMaxSubKeyLen,
510*cdf0e10cSrcweir 			0, 0, 0, 0, 0, 0);
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir 		nMaxSubKeyLen++; // space for trailing '\0'
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir 		lpSubKey = reinterpret_cast<wchar_t*>(
515*cdf0e10cSrcweir 			_alloca(nMaxSubKeyLen*sizeof(wchar_t)));
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir 		while (ERROR_SUCCESS == rc)
518*cdf0e10cSrcweir         {
519*cdf0e10cSrcweir 			DWORD nLen = nMaxSubKeyLen;
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir 			rc = RegEnumKeyExW(
522*cdf0e10cSrcweir 				hKey,
523*cdf0e10cSrcweir                 0,       // always index zero
524*cdf0e10cSrcweir                 lpSubKey,
525*cdf0e10cSrcweir                 &nLen,
526*cdf0e10cSrcweir                 0, 0, 0, 0);
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir             if (ERROR_NO_MORE_ITEMS == rc)
529*cdf0e10cSrcweir             {
530*cdf0e10cSrcweir 				rc = RegDeleteKeyW(RootKey, Name.c_str());
531*cdf0e10cSrcweir                 break;
532*cdf0e10cSrcweir             }
533*cdf0e10cSrcweir             else if (rc == ERROR_SUCCESS)
534*cdf0e10cSrcweir 			{
535*cdf0e10cSrcweir 				rc = ImplDeleteSubKeyTree(hKey, lpSubKey);
536*cdf0e10cSrcweir 			}
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir 		} // while
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir         RegCloseKey(hKey);
541*cdf0e10cSrcweir 
542*cdf0e10cSrcweir 	} // if
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
545*cdf0e10cSrcweir 		throw RegistryIOException(rc);
546*cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
547*cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
548*cdf0e10cSrcweir 	else if (ERROR_FILE_NOT_FOUND == rc)
549*cdf0e10cSrcweir 		throw RegistryKeyNotFoundException(rc);
550*cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
551*cdf0e10cSrcweir 		throw RegistryException(rc);
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir 	return rc;
554*cdf0e10cSrcweir }
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir //-----------------------------------------------------
557*cdf0e10cSrcweir /** Delete the specified value
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir 		@precond IsOpen = true
560*cdf0e10cSrcweir 				 IsWriteable = true
561*cdf0e10cSrcweir 				 HasValue(Name) = true
562*cdf0e10cSrcweir 
563*cdf0e10cSrcweir 		@throws	RegistryIOException
564*cdf0e10cSrcweir 				RegistryWriteAccessDeniedException
565*cdf0e10cSrcweir 				RegistryValueNotFoundException
566*cdf0e10cSrcweir */
567*cdf0e10cSrcweir void RegistryKeyImplWinNT::DeleteValue(const std::wstring& Name)
568*cdf0e10cSrcweir {
569*cdf0e10cSrcweir 	assert(IsOpen());
570*cdf0e10cSrcweir 	assert(HasValue(Name));
571*cdf0e10cSrcweir 	assert(IsWriteable());
572*cdf0e10cSrcweir 
573*cdf0e10cSrcweir 	LONG rc = RegDeleteValueW(
574*cdf0e10cSrcweir 		m_hSubKey,
575*cdf0e10cSrcweir 		Name.c_str());
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
578*cdf0e10cSrcweir 		throw RegistryIOException(rc);
579*cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
580*cdf0e10cSrcweir 		throw RegistryNoWriteAccessException(rc);
581*cdf0e10cSrcweir 	else if (ERROR_FILE_NOT_FOUND == rc)
582*cdf0e10cSrcweir 		throw RegistryValueNotFoundException(rc);
583*cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
584*cdf0e10cSrcweir 		throw RegistryException(rc);
585*cdf0e10cSrcweir }
586*cdf0e10cSrcweir 
587*cdf0e10cSrcweir //-----------------------------------------------------
588*cdf0e10cSrcweir /** Set the specified registry value
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir 	@precond IsOpen = true
591*cdf0e10cSrcweir 			 IsWriteable = true
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir 	@throws  RegistryIOException
594*cdf0e10cSrcweir 			 RegistryWriteAccessDenyException
595*cdf0e10cSrcweir */
596*cdf0e10cSrcweir void RegistryKeyImplWinNT::SetValue(const RegistryValue& Value)
597*cdf0e10cSrcweir {
598*cdf0e10cSrcweir 	assert(IsOpen());
599*cdf0e10cSrcweir 	assert(IsWriteable());
600*cdf0e10cSrcweir 
601*cdf0e10cSrcweir 	LONG rc = RegSetValueExW(
602*cdf0e10cSrcweir 		m_hSubKey,
603*cdf0e10cSrcweir 		Value->GetName().c_str(),
604*cdf0e10cSrcweir 		0,
605*cdf0e10cSrcweir 		Value->GetType(),
606*cdf0e10cSrcweir 		reinterpret_cast<const unsigned char*>(Value->GetDataBuffer()),
607*cdf0e10cSrcweir 		static_cast<DWORD>(Value->GetDataSize()));
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
610*cdf0e10cSrcweir 		throw RegistryIOException(rc);
611*cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
612*cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
613*cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
614*cdf0e10cSrcweir 		throw RegistryException(rc);
615*cdf0e10cSrcweir }
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir 
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir 
620