1 /**
2  * Copyright: Copyright (c) 2009 Jacob Carlborg. All rights reserved.
3  * Authors: Jacob Carlborg
4  * Version: Initial created: Feb 21, 2009
5  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
6  */
7 module dvm.util.Registry;
8 
9 version (Windows) {} else
10     static assert(false, "dvm.util.Registry is only for Windows");
11 
12 /// High-Level Registry Utilities
13 
14 import mambo.core..string;
15 import dvm.sys.Registry;
16 import dvm.util.Windows;
17 import tango.sys.win32.Types;
18 import tango.sys.win32.UserGdi;
19 
20 public import dvm.sys.Registry :
21     RegRoot,
22     HKEY_CLASSES_ROOT,
23     HKEY_CURRENT_USER,
24     HKEY_LOCAL_MACHINE,
25     HKEY_USERS,
26     HKEY_PERFORMANCE_DATA,
27     HKEY_CURRENT_CONFIG,
28     HKEY_DYN_DATA,
29     RegKeyAccess,
30     RegValueType,
31     RegQueryResult,
32     RegistryException,
33     toString;
34 
35 enum RegKeyOpenMode
36 {
37     Open, Create
38 }
39 
40 scope final class RegistryKey
41 {
42     /// Properties ////////////////////////
43     private RegRoot _root;
44     private string _subKey;
45     private RegKeyAccess _access;
46     private HKEY _hKey;
47     private bool _wasCreated=false;
48 
49     RegRoot root()
50     {
51         return _root;
52     }
53     string subKey()
54     {
55         return _subKey.dup;
56     }
57     RegKeyAccess access()
58     {
59         return _access;
60     }
61     HKEY hKey()
62     {
63         return _hKey;
64     }
65     bool wasCreated()
66     {
67         return _wasCreated;
68     }
69 
70     /// toString ////////////////////////
71     override string toString()
72     {
73         return dvm.sys.Registry.toString(_root) ~ `\` ~ _subKey;
74     }
75 
76     static string toString(RegRoot root, string subKey)
77     {
78         return dvm.sys.Registry.toString(root) ~ `\` ~ subKey;
79     }
80 
81     /// Private Error Handling Utilities ////////////////////////
82     private static string chooseErrorMsg(WinAPIException e, string msg)
83     {
84         if(msg == "")
85         {
86             auto re = cast(RegistryException)e;
87             if(re)
88                 return re.registryMsg;
89         }
90         return msg;
91     }
92 
93     private static void staticErrorKey(WinAPIException e, RegRoot root, string subKey, string msg="")
94     {
95         msg = chooseErrorMsg(e, msg);
96         throw new RegistryException(e.code, toString(root, subKey), true, msg);
97     }
98 
99     private void errorKey(WinAPIException e, string msg="")
100     {
101         msg = chooseErrorMsg(e, msg);
102         throw new RegistryException(e.code, this.toString(), true, msg);
103     }
104 
105     private void errorValue(WinAPIException e, string valueName, string msg="")
106     {
107         msg = chooseErrorMsg(e, msg);
108 
109         if(valueName == "")
110             valueName = "(Default)";
111 
112         throw new RegistryException(e.code, this.toString()~`\`~valueName, false, msg);
113     }
114 
115     /// Constructor/Destructor ////////////////////////
116     this(
117         RegRoot root, string subKey,
118         RegKeyOpenMode create = RegKeyOpenMode.Open,
119         RegKeyAccess access = RegKeyAccess.All
120     )
121     {
122         _root   = root;
123         _subKey = subKey;
124         _access = access;
125 
126         if(create == RegKeyOpenMode.Create)
127         {
128             try _hKey = regCreateKey(cast(HKEY)root, subKey, 0, access, _wasCreated);
129             catch(WinAPIException e) errorKey(e);
130         }
131         else
132         {
133             try _hKey = regOpenKey(cast(HKEY)root, subKey, access);
134             catch(WinAPIException e) errorKey(e);
135         }
136     }
137 
138     ~this()
139     {
140         try regCloseKey(_hKey);
141         catch(WinAPIException e) errorKey(e);
142     }
143 
144     /// Registry Functions ////////////////////////
145     static void deleteKey(RegRoot root, string subKey)
146     {
147         try
148         {
149             scope key = new RegistryKey(root, "", RegKeyOpenMode.Open, RegKeyAccess.Write);
150             regDeleteKey(key._hKey, subKey);
151         }
152         catch(WinAPIException e)
153             staticErrorKey(e, root, subKey);
154     }
155 
156     void deleteValue(string valueName)
157     {
158         try regDeleteValue(_hKey, valueName);
159         catch(WinAPIException e) errorValue(e, valueName);
160     }
161 
162     bool valueExists(string valueName)
163     {
164         try return regValueExists(_hKey, valueName);
165         catch(WinAPIException e)
166         {
167             errorValue(e, valueName);
168             return false;
169         }
170     }
171 
172     /// Registry Functions: setValue //////////////////////////////
173     void setValue(string valueName, RegValueType type, ubyte[] data)
174     {
175         try regSetValue(_hKey, valueName, type, data);
176         catch(WinAPIException e) errorValue(e, valueName);
177     }
178 
179     void setValue(string valueName, string data)
180     {
181         try regSetValue(_hKey, valueName, data);
182         catch(WinAPIException e) errorValue(e, valueName);
183     }
184 
185     void setValueExpand(string valueName, string data)
186     {
187         try regSetValueExpand(_hKey, valueName, data);
188         catch(WinAPIException e) errorValue(e, valueName);
189     }
190 
191     void setValue(string valueName, string data, bool expand)
192     {
193         try regSetValue(_hKey, valueName, data, expand);
194         catch(WinAPIException e) errorValue(e, valueName);
195     }
196 
197     void setValue(string valueName, string[] data)
198     {
199         try regSetValue(_hKey, valueName, data);
200         catch(WinAPIException e) errorValue(e, valueName);
201     }
202 
203     void setValue(string valueName, ubyte[] data)
204     {
205         try regSetValue(_hKey, valueName, data);
206         catch(WinAPIException e) errorValue(e, valueName);
207     }
208 
209     void setValue(string valueName, uint data)
210     {
211         try regSetValue(_hKey, valueName, data);
212         catch(WinAPIException e) errorValue(e, valueName);
213     }
214 
215     void setValue(string valueName)
216     {
217         try regSetValue(_hKey, valueName);
218         catch(WinAPIException e) errorValue(e, valueName);
219     }
220 
221     void setValue(string valueName, RegQueryResult data)
222     {
223         try regSetValue(_hKey, valueName, data);
224         catch(WinAPIException e) errorValue(e, valueName);
225     }
226 
227     /// Registry Functions: getValue //////////////////////////////
228     RegQueryResult getValue(string valueName)
229     {
230         try return regQueryValue(_hKey, valueName);
231         catch(WinAPIException e)
232         {
233             errorValue(e, valueName);
234             return RegQueryResult.init;
235         }
236     }
237 
238     string getValueString(string valueName)
239     {
240         try return regQueryValue!(RegValueType.SZ)(_hKey, valueName);
241         catch(WinAPIException e)
242         {
243             errorValue(e, valueName);
244             return null;
245         }
246     }
247 
248     string getValueExpandString(string valueName)
249     {
250         try return regQueryValue!(RegValueType.EXPAND_SZ)(_hKey, valueName);
251         catch(WinAPIException e)
252         {
253             errorValue(e, valueName);
254             return null;
255         }
256     }
257 
258     string[] getValueStringArray(string valueName)
259     {
260         try return regQueryValue!(RegValueType.MULTI_SZ)(_hKey, valueName);
261         catch(WinAPIException e)
262         {
263             errorValue(e, valueName);
264             return null;
265         }
266     }
267 
268     ubyte[] getValueBinary(string valueName)
269     {
270         try return regQueryValue!(RegValueType.BINARY)(_hKey, valueName);
271         catch(WinAPIException e)
272         {
273             errorValue(e, valueName);
274             return null;
275         }
276     }
277 
278     uint getValueUInt(string valueName)
279     {
280         try return regQueryValue!(RegValueType.DWORD)(_hKey, valueName);
281         catch(WinAPIException e)
282         {
283             errorValue(e, valueName);
284             return uint.max;
285         }
286     }
287 }