FSF GCC merge 02/23/03
[official-gcc.git] / gcc / ada / g-regist.adb
blobb1e963cf6dc4efd3a5b91a61d4d1729608a6bdb9
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- G N A T . R E G I S T R Y --
6 -- --
7 -- B o d y --
8 -- --
9 -- --
10 -- Copyright (C) 2001 Free Software Foundation, Inc. --
11 -- --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
22 -- --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
29 -- --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 -- --
32 ------------------------------------------------------------------------------
34 with Ada.Exceptions;
35 with Interfaces.C;
36 with System;
38 package body GNAT.Registry is
40 use Ada;
41 use System;
43 ------------------------------
44 -- Binding to the Win32 API --
45 ------------------------------
47 subtype LONG is Interfaces.C.long;
48 subtype ULONG is Interfaces.C.unsigned_long;
49 subtype DWORD is ULONG;
51 type PULONG is access all ULONG;
52 subtype PDWORD is PULONG;
53 subtype LPDWORD is PDWORD;
55 subtype Error_Code is LONG;
57 subtype REGSAM is LONG;
59 type PHKEY is access all HKEY;
61 ERROR_SUCCESS : constant Error_Code := 0;
63 REG_SZ : constant := 1;
65 function RegCloseKey (Key : HKEY) return LONG;
66 pragma Import (Stdcall, RegCloseKey, "RegCloseKey");
68 function RegCreateKeyEx
69 (Key : HKEY;
70 lpSubKey : Address;
71 Reserved : DWORD;
72 lpClass : Address;
73 dwOptions : DWORD;
74 samDesired : REGSAM;
75 lpSecurityAttributes : Address;
76 phkResult : PHKEY;
77 lpdwDisposition : LPDWORD)
78 return LONG;
79 pragma Import (Stdcall, RegCreateKeyEx, "RegCreateKeyExA");
81 function RegDeleteKey
82 (Key : HKEY;
83 lpSubKey : Address)
84 return LONG;
85 pragma Import (Stdcall, RegDeleteKey, "RegDeleteKeyA");
87 function RegDeleteValue
88 (Key : HKEY;
89 lpValueName : Address)
90 return LONG;
91 pragma Import (Stdcall, RegDeleteValue, "RegDeleteValueA");
93 function RegEnumValue
94 (Key : HKEY;
95 dwIndex : DWORD;
96 lpValueName : Address;
97 lpcbValueName : LPDWORD;
98 lpReserved : LPDWORD;
99 lpType : LPDWORD;
100 lpData : Address;
101 lpcbData : LPDWORD)
102 return LONG;
103 pragma Import (Stdcall, RegEnumValue, "RegEnumValueA");
105 function RegOpenKeyEx
106 (Key : HKEY;
107 lpSubKey : Address;
108 ulOptions : DWORD;
109 samDesired : REGSAM;
110 phkResult : PHKEY)
111 return LONG;
112 pragma Import (Stdcall, RegOpenKeyEx, "RegOpenKeyExA");
114 function RegQueryValueEx
115 (Key : HKEY;
116 lpValueName : Address;
117 lpReserved : LPDWORD;
118 lpType : LPDWORD;
119 lpData : Address;
120 lpcbData : LPDWORD)
121 return LONG;
122 pragma Import (Stdcall, RegQueryValueEx, "RegQueryValueExA");
124 function RegSetValueEx
125 (Key : HKEY;
126 lpValueName : Address;
127 Reserved : DWORD;
128 dwType : DWORD;
129 lpData : Address;
130 cbData : DWORD)
131 return LONG;
132 pragma Import (Stdcall, RegSetValueEx, "RegSetValueExA");
134 -----------------------
135 -- Local Subprograms --
136 -----------------------
138 function To_C_Mode (Mode : Key_Mode) return REGSAM;
139 -- Returns the Win32 mode value for the Key_Mode value.
141 procedure Check_Result (Result : LONG; Message : String);
142 -- Checks value Result and raise the exception Registry_Error if it is not
143 -- equal to ERROR_SUCCESS. Message and the error value (Result) is added
144 -- to the exception message.
146 ------------------
147 -- Check_Result --
148 ------------------
150 procedure Check_Result (Result : LONG; Message : String) is
151 use type LONG;
153 begin
154 if Result /= ERROR_SUCCESS then
155 Exceptions.Raise_Exception
156 (Registry_Error'Identity,
157 Message & " (" & LONG'Image (Result) & ')');
158 end if;
159 end Check_Result;
161 ---------------
162 -- Close_Key --
163 ---------------
165 procedure Close_Key (Key : HKEY) is
166 Result : LONG;
168 begin
169 Result := RegCloseKey (Key);
170 Check_Result (Result, "Close_Key");
171 end Close_Key;
173 ----------------
174 -- Create_Key --
175 ----------------
177 function Create_Key
178 (From_Key : HKEY;
179 Sub_Key : String;
180 Mode : Key_Mode := Read_Write)
181 return HKEY
183 use type REGSAM;
184 use type DWORD;
186 REG_OPTION_NON_VOLATILE : constant := 16#0#;
188 C_Sub_Key : constant String := Sub_Key & ASCII.Nul;
189 C_Class : constant String := "" & ASCII.Nul;
190 C_Mode : constant REGSAM := To_C_Mode (Mode);
192 New_Key : aliased HKEY;
193 Result : LONG;
194 Dispos : aliased DWORD;
196 begin
197 Result := RegCreateKeyEx
198 (From_Key,
199 C_Sub_Key (C_Sub_Key'First)'Address,
201 C_Class (C_Class'First)'Address,
202 REG_OPTION_NON_VOLATILE,
203 C_Mode,
204 Null_Address,
205 New_Key'Unchecked_Access,
206 Dispos'Unchecked_Access);
208 Check_Result (Result, "Create_Key " & Sub_Key);
209 return New_Key;
210 end Create_Key;
212 ----------------
213 -- Delete_Key --
214 ----------------
216 procedure Delete_Key (From_Key : HKEY; Sub_Key : String) is
217 C_Sub_Key : constant String := Sub_Key & ASCII.Nul;
218 Result : LONG;
220 begin
221 Result := RegDeleteKey (From_Key, C_Sub_Key (C_Sub_Key'First)'Address);
222 Check_Result (Result, "Delete_Key " & Sub_Key);
223 end Delete_Key;
225 ------------------
226 -- Delete_Value --
227 ------------------
229 procedure Delete_Value (From_Key : HKEY; Sub_Key : String) is
230 C_Sub_Key : constant String := Sub_Key & ASCII.Nul;
231 Result : LONG;
233 begin
234 Result := RegDeleteValue (From_Key, C_Sub_Key (C_Sub_Key'First)'Address);
235 Check_Result (Result, "Delete_Value " & Sub_Key);
236 end Delete_Value;
238 -------------------------
239 -- For_Every_Key_Value --
240 -------------------------
242 procedure For_Every_Key_Value (From_Key : HKEY) is
243 use type LONG;
244 use type ULONG;
246 Index : ULONG := 0;
247 Result : LONG;
249 Sub_Key : String (1 .. 100);
250 pragma Warnings (Off, Sub_Key);
252 Value : String (1 .. 100);
253 pragma Warnings (Off, Value);
255 Size_Sub_Key : aliased ULONG;
256 Size_Value : aliased ULONG;
257 Type_Sub_Key : aliased DWORD;
259 Quit : Boolean;
261 begin
262 loop
263 Size_Sub_Key := Sub_Key'Length;
264 Size_Value := Value'Length;
266 Result := RegEnumValue
267 (From_Key, Index,
268 Sub_Key (1)'Address,
269 Size_Sub_Key'Unchecked_Access,
270 null,
271 Type_Sub_Key'Unchecked_Access,
272 Value (1)'Address,
273 Size_Value'Unchecked_Access);
275 exit when not (Result = ERROR_SUCCESS);
277 if Type_Sub_Key = REG_SZ then
278 Quit := False;
280 Action (Natural (Index) + 1,
281 Sub_Key (1 .. Integer (Size_Sub_Key)),
282 Value (1 .. Integer (Size_Value) - 1),
283 Quit);
285 exit when Quit;
287 Index := Index + 1;
288 end if;
290 end loop;
291 end For_Every_Key_Value;
293 ----------------
294 -- Key_Exists --
295 ----------------
297 function Key_Exists
298 (From_Key : HKEY;
299 Sub_Key : String)
300 return Boolean
302 New_Key : HKEY;
304 begin
305 New_Key := Open_Key (From_Key, Sub_Key);
306 Close_Key (New_Key);
308 -- We have been able to open the key so it exists
310 return True;
312 exception
313 when Registry_Error =>
315 -- An error occurred, the key was not found
317 return False;
318 end Key_Exists;
320 --------------
321 -- Open_Key --
322 --------------
324 function Open_Key
325 (From_Key : HKEY;
326 Sub_Key : String;
327 Mode : Key_Mode := Read_Only)
328 return HKEY
330 use type REGSAM;
332 C_Sub_Key : constant String := Sub_Key & ASCII.Nul;
333 C_Mode : constant REGSAM := To_C_Mode (Mode);
335 New_Key : aliased HKEY;
336 Result : LONG;
338 begin
339 Result := RegOpenKeyEx
340 (From_Key,
341 C_Sub_Key (C_Sub_Key'First)'Address,
343 C_Mode,
344 New_Key'Unchecked_Access);
346 Check_Result (Result, "Open_Key " & Sub_Key);
347 return New_Key;
348 end Open_Key;
350 -----------------
351 -- Query_Value --
352 -----------------
354 function Query_Value
355 (From_Key : HKEY;
356 Sub_Key : String)
357 return String
359 use type LONG;
360 use type ULONG;
362 Value : String (1 .. 100);
363 pragma Warnings (Off, Value);
365 Size_Value : aliased ULONG;
366 Type_Value : aliased DWORD;
368 C_Sub_Key : constant String := Sub_Key & ASCII.Nul;
369 Result : LONG;
371 begin
372 Size_Value := Value'Length;
374 Result := RegQueryValueEx
375 (From_Key,
376 C_Sub_Key (C_Sub_Key'First)'Address,
377 null,
378 Type_Value'Unchecked_Access,
379 Value (Value'First)'Address,
380 Size_Value'Unchecked_Access);
382 Check_Result (Result, "Query_Value " & Sub_Key & " key");
384 return Value (1 .. Integer (Size_Value - 1));
385 end Query_Value;
387 ---------------
388 -- Set_Value --
389 ---------------
391 procedure Set_Value
392 (From_Key : HKEY;
393 Sub_Key : String;
394 Value : String)
396 C_Sub_Key : constant String := Sub_Key & ASCII.Nul;
397 C_Value : constant String := Value & ASCII.Nul;
399 Result : LONG;
401 begin
402 Result := RegSetValueEx
403 (From_Key,
404 C_Sub_Key (C_Sub_Key'First)'Address,
406 REG_SZ,
407 C_Value (C_Value'First)'Address,
408 C_Value'Length);
410 Check_Result (Result, "Set_Value " & Sub_Key & " key");
411 end Set_Value;
413 ---------------
414 -- To_C_Mode --
415 ---------------
417 function To_C_Mode (Mode : Key_Mode) return REGSAM is
418 use type REGSAM;
420 KEY_READ : constant := 16#20019#;
421 KEY_WRITE : constant := 16#20006#;
423 begin
424 case Mode is
425 when Read_Only =>
426 return KEY_READ;
428 when Read_Write =>
429 return KEY_READ + KEY_WRITE;
430 end case;
431 end To_C_Mode;
433 end GNAT.Registry;