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