1*32b1fd08SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*32b1fd08SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*32b1fd08SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*32b1fd08SAndrew Rist  * distributed with this work for additional information
6*32b1fd08SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*32b1fd08SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*32b1fd08SAndrew Rist  * "License"); you may not use this file except in compliance
9*32b1fd08SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*32b1fd08SAndrew Rist  *
11*32b1fd08SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*32b1fd08SAndrew Rist  *
13*32b1fd08SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*32b1fd08SAndrew Rist  * software distributed under the License is distributed on an
15*32b1fd08SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*32b1fd08SAndrew Rist  * KIND, either express or implied.  See the License for the
17*32b1fd08SAndrew Rist  * specific language governing permissions and limitations
18*32b1fd08SAndrew Rist  * under the License.
19*32b1fd08SAndrew Rist  *
20*32b1fd08SAndrew Rist  *************************************************************/
21*32b1fd08SAndrew Rist 
22*32b1fd08SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir //---------------------------------------
25cdf0e10cSrcweir //
26cdf0e10cSrcweir //---------------------------------------
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include "registryw9x.hxx"
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <windows.h>
31cdf0e10cSrcweir #include <malloc.h>
32cdf0e10cSrcweir #include "registryvalueimpl.hxx"
33cdf0e10cSrcweir #include "registryexception.hxx"
34cdf0e10cSrcweir #include "stringconverter.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <assert.h>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #ifdef _MSC_VER
39cdf0e10cSrcweir #pragma warning(disable : 4786 4350)
40cdf0e10cSrcweir #endif
41cdf0e10cSrcweir 
42cdf0e10cSrcweir //---------------------------------------
43cdf0e10cSrcweir //
44cdf0e10cSrcweir //---------------------------------------
45cdf0e10cSrcweir 
46cdf0e10cSrcweir const size_t MAX_TMP_BUFF_SIZE = 1024 * sizeof(wchar_t);
47cdf0e10cSrcweir 
48cdf0e10cSrcweir 
49cdf0e10cSrcweir //############################################
50cdf0e10cSrcweir // Creation
51cdf0e10cSrcweir // only possible through WindowsRegistry class
52cdf0e10cSrcweir //############################################
53cdf0e10cSrcweir 
54cdf0e10cSrcweir 
55cdf0e10cSrcweir //-----------------------------------------------------
56cdf0e10cSrcweir /** Create instance and open the specified Registry key
57cdf0e10cSrcweir */
RegistryKeyImplWin9x(HKEY RootKey,const std::wstring & KeyName)58cdf0e10cSrcweir RegistryKeyImplWin9x::RegistryKeyImplWin9x(HKEY RootKey, const std::wstring& KeyName) :
59cdf0e10cSrcweir 	RegistryKeyImpl(RootKey, KeyName)
60cdf0e10cSrcweir {
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
63cdf0e10cSrcweir //-----------------------------------------------------
64cdf0e10cSrcweir /** Create instance and open the specified Registry key
65cdf0e10cSrcweir */
RegistryKeyImplWin9x(HKEY RootKey)66cdf0e10cSrcweir RegistryKeyImplWin9x::RegistryKeyImplWin9x(HKEY RootKey) :
67cdf0e10cSrcweir 	RegistryKeyImpl(RootKey)
68cdf0e10cSrcweir {
69cdf0e10cSrcweir }
70cdf0e10cSrcweir 
71cdf0e10cSrcweir //-----------------------------------------------------
72cdf0e10cSrcweir /** Create an instances of the specified Registry key,
73cdf0e10cSrcweir 	the key is assumed to be already opened.
74cdf0e10cSrcweir */
RegistryKeyImplWin9x(HKEY RootKey,HKEY SubKey,const std::wstring & KeyName,bool Writeable)75cdf0e10cSrcweir RegistryKeyImplWin9x::RegistryKeyImplWin9x(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable) :
76cdf0e10cSrcweir 	RegistryKeyImpl(RootKey, SubKey, KeyName, Writeable)
77cdf0e10cSrcweir {
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
80cdf0e10cSrcweir 
81cdf0e10cSrcweir //############################################
82cdf0e10cSrcweir // Queries
83cdf0e10cSrcweir //############################################
84cdf0e10cSrcweir 
85cdf0e10cSrcweir 
86cdf0e10cSrcweir //-----------------------------------------------------
87cdf0e10cSrcweir /** The number of sub values of the key at hand
88cdf0e10cSrcweir 
89cdf0e10cSrcweir 	@precond IsOpen = true
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 	@throws
92cdf0e10cSrcweir */
GetSubValueCount() const93cdf0e10cSrcweir size_t RegistryKeyImplWin9x::GetSubValueCount() const
94cdf0e10cSrcweir {
95cdf0e10cSrcweir 	assert(IsOpen());
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 	DWORD nSubValues = 0;
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 	LONG rc = RegQueryInfoKeyA(
100cdf0e10cSrcweir 		m_hSubKey,
101cdf0e10cSrcweir 		0, 0, 0, 0, 0, 0, &nSubValues, 0, 0, 0, 0);
102cdf0e10cSrcweir 
103cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
104cdf0e10cSrcweir 		throw RegistryIOException(rc);
105cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
106cdf0e10cSrcweir 		throw RegistryException(rc);
107cdf0e10cSrcweir 
108cdf0e10cSrcweir 	return nSubValues;
109cdf0e10cSrcweir }
110cdf0e10cSrcweir 
111cdf0e10cSrcweir //-----------------------------------------------------
112cdf0e10cSrcweir /** The number of sub-keys of the key at hand
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 	@precond IsOpen = true
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 	@throws
117cdf0e10cSrcweir */
GetSubKeyCount() const118cdf0e10cSrcweir size_t RegistryKeyImplWin9x::GetSubKeyCount() const
119cdf0e10cSrcweir {
120cdf0e10cSrcweir 	assert(IsOpen());
121cdf0e10cSrcweir 
122cdf0e10cSrcweir 	DWORD nSubKeys = 0;
123cdf0e10cSrcweir 
124cdf0e10cSrcweir 	LONG rc = RegQueryInfoKeyA(
125cdf0e10cSrcweir 		m_hSubKey,
126cdf0e10cSrcweir 		0, 0, 0, &nSubKeys, 0, 0, 0, 0, 0, 0, 0);
127cdf0e10cSrcweir 
128cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
129cdf0e10cSrcweir 		throw RegistryIOException(rc);
130cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
131cdf0e10cSrcweir 		throw RegistryException(rc);
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 	return nSubKeys;
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir //-----------------------------------------------------
137cdf0e10cSrcweir /**
138cdf0e10cSrcweir */
GetSubKeyNames() const139cdf0e10cSrcweir StringListPtr RegistryKeyImplWin9x::GetSubKeyNames() const
140cdf0e10cSrcweir {
141cdf0e10cSrcweir 	assert(IsOpen());
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 	char        buff[1024];
144cdf0e10cSrcweir 	DWORD   buff_size = sizeof(buff);
145cdf0e10cSrcweir 	FILETIME ftime;
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 	StringList* key_names = new StringList();
148cdf0e10cSrcweir 
149cdf0e10cSrcweir 	LONG rc = ERROR_SUCCESS;
150cdf0e10cSrcweir 
151cdf0e10cSrcweir 	for (DWORD i = 0; /* left empty */; i++)
152cdf0e10cSrcweir 	{
153cdf0e10cSrcweir 		rc = RegEnumKeyExA(
154cdf0e10cSrcweir 			m_hSubKey, i, buff, &buff_size,
155cdf0e10cSrcweir 			0, 0, 0, &ftime);
156cdf0e10cSrcweir 
157cdf0e10cSrcweir 		if (ERROR_SUCCESS != rc &&
158cdf0e10cSrcweir 			ERROR_MORE_DATA != rc)
159cdf0e10cSrcweir 			break;
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 		buff_size = sizeof(buff);
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 		key_names->push_back(AnsiToUnicodeString(buff));
164cdf0e10cSrcweir 	}
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
167cdf0e10cSrcweir 		throw RegistryIOException(rc);
168cdf0e10cSrcweir 	else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
169cdf0e10cSrcweir 		throw RegistryException(rc);
170cdf0e10cSrcweir 
171cdf0e10cSrcweir 	return (StringListPtr) key_names;
172cdf0e10cSrcweir }
173cdf0e10cSrcweir 
174cdf0e10cSrcweir //-----------------------------------------------------
175cdf0e10cSrcweir /**
176cdf0e10cSrcweir */
GetSubValueNames() const177cdf0e10cSrcweir StringListPtr RegistryKeyImplWin9x::GetSubValueNames() const
178cdf0e10cSrcweir {
179cdf0e10cSrcweir 	assert(IsOpen());
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 	char        buff[1024];
182cdf0e10cSrcweir 	DWORD   buff_size = sizeof(buff);
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 	StringList* value_names = new StringList();
185cdf0e10cSrcweir 
186cdf0e10cSrcweir 	LONG rc = ERROR_SUCCESS;
187cdf0e10cSrcweir 
188cdf0e10cSrcweir 	for (DWORD i = 0; /* left empty */; i++)
189cdf0e10cSrcweir 	{
190cdf0e10cSrcweir         rc = RegEnumValueA(
191cdf0e10cSrcweir 			m_hSubKey, i, buff, &buff_size,
192cdf0e10cSrcweir 			0, 0, 0, 0);
193cdf0e10cSrcweir 
194cdf0e10cSrcweir 		if (ERROR_SUCCESS != rc &&
195cdf0e10cSrcweir 			ERROR_MORE_DATA != rc)
196cdf0e10cSrcweir 			break;
197cdf0e10cSrcweir 
198cdf0e10cSrcweir 		buff_size = sizeof(buff);
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 		value_names->push_back(AnsiToUnicodeString(buff));
201cdf0e10cSrcweir 	}
202cdf0e10cSrcweir 
203cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
204cdf0e10cSrcweir 		throw RegistryIOException(rc);
205cdf0e10cSrcweir 	else if (ERROR_NO_MORE_ITEMS != rc && ERROR_SUCCESS != rc)
206cdf0e10cSrcweir 		throw RegistryException(rc);
207cdf0e10cSrcweir 
208cdf0e10cSrcweir 	return (StringListPtr) value_names;
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
211cdf0e10cSrcweir //-----------------------------------------------------
212cdf0e10cSrcweir /** Get the specified registry value
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 	@precond IsOpen = true
215cdf0e10cSrcweir */
GetValue(const std::wstring & Name) const216cdf0e10cSrcweir RegistryValue RegistryKeyImplWin9x::GetValue(const std::wstring& Name) const
217cdf0e10cSrcweir {
218cdf0e10cSrcweir 	assert(IsOpen());
219cdf0e10cSrcweir 
220cdf0e10cSrcweir 	DWORD Type;
221cdf0e10cSrcweir 	char  buff[MAX_TMP_BUFF_SIZE];
222cdf0e10cSrcweir 	DWORD size = sizeof(buff);
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 	LONG rc = RegQueryValueExA(
225cdf0e10cSrcweir 		m_hSubKey,
226cdf0e10cSrcweir 		UnicodeToAnsiString(Name).c_str(),
227cdf0e10cSrcweir 		0,
228cdf0e10cSrcweir 		&Type,
229cdf0e10cSrcweir 		reinterpret_cast<LPBYTE>(buff),
230cdf0e10cSrcweir 		&size);
231cdf0e10cSrcweir 
232cdf0e10cSrcweir 	if (ERROR_FILE_NOT_FOUND == rc)
233cdf0e10cSrcweir 		throw RegistryValueNotFoundException(rc);
234cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
235cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
236cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
237cdf0e10cSrcweir 		throw RegistryException(rc);
238cdf0e10cSrcweir 
239cdf0e10cSrcweir 	RegistryValue regval;
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 	if (REG_DWORD == Type)
242cdf0e10cSrcweir     {
243cdf0e10cSrcweir 		regval = RegistryValue(new RegistryValueImpl(Name, *(reinterpret_cast<int*>(buff))));
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir 	else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
246cdf0e10cSrcweir     {
247cdf0e10cSrcweir         if (size > 0)
248cdf0e10cSrcweir             regval = RegistryValue(new RegistryValueImpl(Name, std::string(reinterpret_cast<char*>(buff))));
249cdf0e10cSrcweir         else
250cdf0e10cSrcweir             regval = RegistryValue(new RegistryValueImpl(Name, std::string()));
251cdf0e10cSrcweir     }
252cdf0e10cSrcweir 	else
253cdf0e10cSrcweir     {
254cdf0e10cSrcweir 		assert(false);
255cdf0e10cSrcweir     }
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 	return regval;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
260cdf0e10cSrcweir //-----------------------------------------------------
261cdf0e10cSrcweir /** Get the specified registry value, return the given
262cdf0e10cSrcweir 	default value if value not found
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 	@precond IsOpen = true
265cdf0e10cSrcweir */
GetValue(const std::wstring & Name,const RegistryValue & Default) const266cdf0e10cSrcweir RegistryValue RegistryKeyImplWin9x::GetValue(const std::wstring& Name, const RegistryValue& Default) const
267cdf0e10cSrcweir {
268cdf0e10cSrcweir 	assert(IsOpen());
269cdf0e10cSrcweir 
270cdf0e10cSrcweir 	DWORD Type;
271cdf0e10cSrcweir 	char  buff[MAX_TMP_BUFF_SIZE];
272cdf0e10cSrcweir 	DWORD size = sizeof(buff);
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 	LONG rc = RegQueryValueExA(
275cdf0e10cSrcweir 		m_hSubKey,
276cdf0e10cSrcweir 		UnicodeToAnsiString(Name).c_str(),
277cdf0e10cSrcweir 		0,
278cdf0e10cSrcweir 		&Type,
279cdf0e10cSrcweir 		reinterpret_cast<LPBYTE>(buff),
280cdf0e10cSrcweir 		&size);
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 	if (ERROR_FILE_NOT_FOUND == rc)
283cdf0e10cSrcweir 	{
284cdf0e10cSrcweir         #if !defined(__MINGW32__) && (_MSC_VER < 1300)
285cdf0e10cSrcweir 		return Default;
286cdf0e10cSrcweir 		#else
287cdf0e10cSrcweir 		RegistryValue regval_ptr;
288cdf0e10cSrcweir 		regval_ptr = RegistryValue(new RegistryValueImpl(*Default));
289cdf0e10cSrcweir 		return regval_ptr;
290cdf0e10cSrcweir 		#endif
291cdf0e10cSrcweir 		}
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 	if (ERROR_ACCESS_DENIED == rc)
294cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
295cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
296cdf0e10cSrcweir 		throw RegistryException(rc);
297cdf0e10cSrcweir 
298cdf0e10cSrcweir 	RegistryValue regval;
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 	if (REG_DWORD == Type)
301cdf0e10cSrcweir 		regval = RegistryValue(new RegistryValueImpl(Name, *reinterpret_cast<int*>(buff)));
302cdf0e10cSrcweir 	else if (REG_SZ == Type || REG_EXPAND_SZ == Type || REG_MULTI_SZ == Type)
303cdf0e10cSrcweir 		regval = RegistryValue(new RegistryValueImpl(Name, std::string(reinterpret_cast<char*>(buff))));
304cdf0e10cSrcweir 	else
305cdf0e10cSrcweir 		assert(false);
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 	return regval;
308cdf0e10cSrcweir }
309cdf0e10cSrcweir 
310cdf0e10cSrcweir 
311cdf0e10cSrcweir //############################################
312cdf0e10cSrcweir // Commands
313cdf0e10cSrcweir //############################################
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 
316cdf0e10cSrcweir //-----------------------------------------------------
317cdf0e10cSrcweir /** Open the registry key, has no effect if
318cdf0e10cSrcweir 	the key is already open
319cdf0e10cSrcweir 
320cdf0e10cSrcweir 	@precond IsOpen = false
321cdf0e10cSrcweir 
322cdf0e10cSrcweir 	@throws RegistryKeyNotFoundException
323cdf0e10cSrcweir 			RegistryWriteAccessDenyException
324cdf0e10cSrcweir 			RegistryAccessDenyException
325cdf0e10cSrcweir */
Open(bool Writeable)326cdf0e10cSrcweir void RegistryKeyImplWin9x::Open(bool Writeable)
327cdf0e10cSrcweir {
328cdf0e10cSrcweir 	assert(!IsOpen());
329cdf0e10cSrcweir 
330cdf0e10cSrcweir 	REGSAM regsam = KEY_READ;
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 	if (Writeable)
333cdf0e10cSrcweir 		regsam |= KEY_WRITE;
334cdf0e10cSrcweir 
335cdf0e10cSrcweir 	LONG rc = RegOpenKeyExA(
336cdf0e10cSrcweir 		m_hRootKey,
337cdf0e10cSrcweir 		UnicodeToAnsiString(m_KeyName).c_str(),
338cdf0e10cSrcweir 		0,
339cdf0e10cSrcweir 		regsam,
340cdf0e10cSrcweir 		&m_hSubKey);
341cdf0e10cSrcweir 
342cdf0e10cSrcweir 	if (ERROR_FILE_NOT_FOUND == rc)
343cdf0e10cSrcweir 		throw RegistryKeyNotFoundException(rc);
344cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
345cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
346cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
347cdf0e10cSrcweir 		throw RegistryException(rc);
348cdf0e10cSrcweir 
349cdf0e10cSrcweir 	m_IsWriteable = Writeable;
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 	assert(IsOpen());
352cdf0e10cSrcweir }
353cdf0e10cSrcweir 
354cdf0e10cSrcweir //-----------------------------------------------------
355cdf0e10cSrcweir /** Open the specified sub-key of the registry key
356cdf0e10cSrcweir 	at hand
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 	@precond IsOpen = true
359cdf0e10cSrcweir 			 HasSubKey(Name) = true
360cdf0e10cSrcweir 
361cdf0e10cSrcweir 	@throws RegistryIOException
362cdf0e10cSrcweir 			RegistryKeyNotFoundException
363cdf0e10cSrcweir 			RegistryAccessDeniedException
364cdf0e10cSrcweir */
OpenSubKey(const std::wstring & Name,bool Writeable)365cdf0e10cSrcweir RegistryKey RegistryKeyImplWin9x::OpenSubKey(const std::wstring& Name, bool Writeable)
366cdf0e10cSrcweir {
367cdf0e10cSrcweir 	RegistryKey regkey(new RegistryKeyImplWin9x(m_hSubKey, Name));
368cdf0e10cSrcweir 	regkey->Open(Writeable);
369cdf0e10cSrcweir 	return regkey;
370cdf0e10cSrcweir }
371cdf0e10cSrcweir 
372cdf0e10cSrcweir //-----------------------------------------------------
373cdf0e10cSrcweir /** Creates a new sub-key below the key at hand
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 	@precond IsOpen = true
376cdf0e10cSrcweir 			 IsWriteable = true
377cdf0e10cSrcweir 
378cdf0e10cSrcweir 	@throws  RegistryIOException
379cdf0e10cSrcweir 			 RegistryWriteAccessDenyException
380cdf0e10cSrcweir */
381cdf0e10cSrcweir 
CreateSubKey(const std::wstring & Name)382cdf0e10cSrcweir RegistryKey RegistryKeyImplWin9x::CreateSubKey(const std::wstring& Name)
383cdf0e10cSrcweir {
384cdf0e10cSrcweir 	assert(IsOpen());
385cdf0e10cSrcweir 	assert(IsWriteable());
386cdf0e10cSrcweir 
387cdf0e10cSrcweir 	HKEY hRoot = IsRootKey() ? m_hRootKey : m_hSubKey;
388cdf0e10cSrcweir 
389cdf0e10cSrcweir 	HKEY hKey;
390cdf0e10cSrcweir 
391cdf0e10cSrcweir 	LONG rc = RegCreateKeyExA(
392cdf0e10cSrcweir 		hRoot,
393cdf0e10cSrcweir 		UnicodeToAnsiString(Name).c_str(),
394cdf0e10cSrcweir 		0,
395cdf0e10cSrcweir 		0,
396cdf0e10cSrcweir 		REG_OPTION_NON_VOLATILE,
397cdf0e10cSrcweir 		KEY_READ | KEY_WRITE,
398cdf0e10cSrcweir 		0,
399cdf0e10cSrcweir 		&hKey,
400cdf0e10cSrcweir 		0);
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
403cdf0e10cSrcweir 		throw RegistryIOException(rc);
404cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
405cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
406cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
407cdf0e10cSrcweir 		throw RegistryException(rc);
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 	return RegistryKey(new RegistryKeyImplWin9x(hRoot, hKey, Name));
410cdf0e10cSrcweir }
411cdf0e10cSrcweir 
412cdf0e10cSrcweir //-----------------------------------------------------
413cdf0e10cSrcweir /** Deletes a sub-key below the key at hand, the
414cdf0e10cSrcweir 	key must not have sub-keys
415cdf0e10cSrcweir 
416cdf0e10cSrcweir 	@precond IsOpen = true
417cdf0e10cSrcweir 			 IsWriteable = true
418cdf0e10cSrcweir 
419cdf0e10cSrcweir 	@throws  RegistryIOException
420cdf0e10cSrcweir 			 RegistryWriteAccessDenyException
421cdf0e10cSrcweir */
DeleteSubKey(const std::wstring & Name)422cdf0e10cSrcweir void RegistryKeyImplWin9x::DeleteSubKey(const std::wstring& Name)
423cdf0e10cSrcweir {
424cdf0e10cSrcweir 	assert(IsOpen());
425cdf0e10cSrcweir 	assert(IsWriteable());
426cdf0e10cSrcweir 	assert(HasSubKey(Name));
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 	RegistryKey SubKey = OpenSubKey(Name);
429cdf0e10cSrcweir 
430cdf0e10cSrcweir 	size_t nSubKeyCount = SubKey->GetSubKeyCount();
431cdf0e10cSrcweir 
432cdf0e10cSrcweir 	assert(0 == nSubKeyCount);
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 	if (nSubKeyCount)
435cdf0e10cSrcweir 		throw RegistryInvalidOperationException(ERROR_NOT_SUPPORTED);
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 	LONG rc = RegDeleteKeyA(m_hSubKey, UnicodeToAnsiString(Name).c_str());
438cdf0e10cSrcweir 
439cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
440cdf0e10cSrcweir 		throw RegistryIOException(rc);
441cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
442cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
443cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
444cdf0e10cSrcweir 		throw RegistryException(rc);
445cdf0e10cSrcweir }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir //-----------------------------------------------------
448cdf0e10cSrcweir /** Deletes a sub-key below the key at hand with all
449cdf0e10cSrcweir 	its sub-keys
450cdf0e10cSrcweir 
451cdf0e10cSrcweir 	@precond IsOpen = true
452cdf0e10cSrcweir 			 IsWriteable = true;
453cdf0e10cSrcweir 
454cdf0e10cSrcweir 	@throws  RegistryIOException
455cdf0e10cSrcweir 			 RegistryWriteAccessDenyException
456cdf0e10cSrcweir */
DeleteSubKeyTree(const std::wstring & Name)457cdf0e10cSrcweir void RegistryKeyImplWin9x::DeleteSubKeyTree(const std::wstring& Name)
458cdf0e10cSrcweir {
459cdf0e10cSrcweir 	LONG rc = RegDeleteKeyA(m_hSubKey, UnicodeToAnsiString(Name).c_str());
460cdf0e10cSrcweir 
461cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
462cdf0e10cSrcweir 		throw RegistryIOException(rc);
463cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
464cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
465cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
466cdf0e10cSrcweir 		throw RegistryException(rc);
467cdf0e10cSrcweir }
468cdf0e10cSrcweir 
469cdf0e10cSrcweir //-----------------------------------------------------
470cdf0e10cSrcweir /** Delete the specified value
471cdf0e10cSrcweir 
472cdf0e10cSrcweir 		@precond IsOpen = true
473cdf0e10cSrcweir 				 IsWriteable = true
474cdf0e10cSrcweir 				 HasValue(Name) = true
475cdf0e10cSrcweir 
476cdf0e10cSrcweir 		@throws	RegistryIOException
477cdf0e10cSrcweir 				RegistryWriteAccessDeniedException
478cdf0e10cSrcweir 				RegistryValueNotFoundException
479cdf0e10cSrcweir */
DeleteValue(const std::wstring & Name)480cdf0e10cSrcweir void RegistryKeyImplWin9x::DeleteValue(const std::wstring& Name)
481cdf0e10cSrcweir {
482cdf0e10cSrcweir 	assert(IsOpen());
483cdf0e10cSrcweir 	assert(HasValue(Name));
484cdf0e10cSrcweir 	assert(IsWriteable());
485cdf0e10cSrcweir 
486cdf0e10cSrcweir 	LONG rc = RegDeleteValueA(
487cdf0e10cSrcweir 		m_hSubKey,
488cdf0e10cSrcweir 		UnicodeToAnsiString(Name).c_str());
489cdf0e10cSrcweir 
490cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
491cdf0e10cSrcweir 		throw RegistryIOException(rc);
492cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
493cdf0e10cSrcweir 		throw RegistryNoWriteAccessException(rc);
494cdf0e10cSrcweir 	else if (ERROR_FILE_NOT_FOUND == rc)
495cdf0e10cSrcweir 		throw RegistryValueNotFoundException(rc);
496cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
497cdf0e10cSrcweir 		throw RegistryException(rc);
498cdf0e10cSrcweir }
499cdf0e10cSrcweir 
500cdf0e10cSrcweir //-----------------------------------------------------
501cdf0e10cSrcweir /** Set the specified registry value
502cdf0e10cSrcweir 
503cdf0e10cSrcweir 	@precond IsOpen = true
504cdf0e10cSrcweir 			 IsWriteable = true
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 	@throws  RegistryIOException
507cdf0e10cSrcweir 			 RegistryWriteAccessDenyException
508cdf0e10cSrcweir */
SetValue(const RegistryValue & Value)509cdf0e10cSrcweir void RegistryKeyImplWin9x::SetValue(const RegistryValue& Value)
510cdf0e10cSrcweir {
511cdf0e10cSrcweir 	assert(IsOpen());
512cdf0e10cSrcweir 	assert(IsWriteable());
513cdf0e10cSrcweir 
514cdf0e10cSrcweir 	LONG rc = ERROR_SUCCESS;
515cdf0e10cSrcweir 
516cdf0e10cSrcweir 	if (REG_SZ == Value->GetType())
517cdf0e10cSrcweir 	{
518cdf0e10cSrcweir 		std::string AnsiStr = Value->GetDataAsAnsiString();
519cdf0e10cSrcweir 
520cdf0e10cSrcweir 		rc = RegSetValueExA(
521cdf0e10cSrcweir 			m_hSubKey,
522cdf0e10cSrcweir 			UnicodeToAnsiString(Value->GetName()).c_str(),
523cdf0e10cSrcweir 			0,
524cdf0e10cSrcweir 			Value->GetType(),
525cdf0e10cSrcweir 			reinterpret_cast<const unsigned char*>(AnsiStr.c_str()),
526cdf0e10cSrcweir 			static_cast<DWORD>((AnsiStr.length() + 1)));
527cdf0e10cSrcweir 	}
528cdf0e10cSrcweir 	else
529cdf0e10cSrcweir 	{
530cdf0e10cSrcweir 		rc = RegSetValueExA(
531cdf0e10cSrcweir 			m_hSubKey,
532cdf0e10cSrcweir 			UnicodeToAnsiString(Value->GetName()).c_str(),
533cdf0e10cSrcweir 			0,
534cdf0e10cSrcweir 			Value->GetType(),
535cdf0e10cSrcweir 			reinterpret_cast<const unsigned char*>(Value->GetDataBuffer()),
536cdf0e10cSrcweir 			static_cast<DWORD>(Value->GetDataSize()));
537cdf0e10cSrcweir 	}
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 	if (ERROR_INVALID_HANDLE == rc)
540cdf0e10cSrcweir 		throw RegistryIOException(rc);
541cdf0e10cSrcweir 	else if (ERROR_ACCESS_DENIED == rc)
542cdf0e10cSrcweir 		throw RegistryAccessDeniedException(rc);
543cdf0e10cSrcweir 	else if (ERROR_SUCCESS != rc)
544cdf0e10cSrcweir 		throw RegistryException(rc);
545cdf0e10cSrcweir }
546cdf0e10cSrcweir 
547