------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                         G N A T . R E G I S T R Y                        --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--           Copyright (C) 2001-2021, Free Software Foundation, Inc.        --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Interfaces.C;
with System;
with GNAT.Directory_Operations;

package body GNAT.Registry is

   use System;

   ------------------------------
   -- Binding to the Win32 API --
   ------------------------------

   subtype LONG is Interfaces.C.long;
   subtype ULONG is Interfaces.C.unsigned_long;
   subtype DWORD is ULONG;

   type    PULONG is access all ULONG;
   subtype PDWORD is PULONG;
   subtype LPDWORD is PDWORD;

   subtype Error_Code is LONG;

   subtype REGSAM is LONG;

   type PHKEY is access all HKEY;

   ERROR_SUCCESS : constant Error_Code := 0;

   REG_SZ        : constant := 1;
   REG_EXPAND_SZ : constant := 2;

   function RegCloseKey (Key : HKEY) return LONG;
   pragma Import (Stdcall, RegCloseKey, "RegCloseKey");

   function RegCreateKeyEx
     (Key                  : HKEY;
      lpSubKey             : Address;
      Reserved             : DWORD;
      lpClass              : Address;
      dwOptions            : DWORD;
      samDesired           : REGSAM;
      lpSecurityAttributes : Address;
      phkResult            : PHKEY;
      lpdwDisposition      : LPDWORD)
      return                 LONG;
   pragma Import (Stdcall, RegCreateKeyEx, "RegCreateKeyExA");

   function RegDeleteKey
     (Key      : HKEY;
      lpSubKey : Address) return LONG;
   pragma Import (Stdcall, RegDeleteKey, "RegDeleteKeyA");

   function RegDeleteValue
     (Key         : HKEY;
      lpValueName : Address) return LONG;
   pragma Import (Stdcall, RegDeleteValue, "RegDeleteValueA");

   function RegEnumValue
     (Key           : HKEY;
      dwIndex       : DWORD;
      lpValueName   : Address;
      lpcbValueName : LPDWORD;
      lpReserved    : LPDWORD;
      lpType        : LPDWORD;
      lpData        : Address;
      lpcbData      : LPDWORD) return LONG;
   pragma Import (Stdcall, RegEnumValue, "RegEnumValueA");

   function RegOpenKeyEx
     (Key        : HKEY;
      lpSubKey   : Address;
      ulOptions  : DWORD;
      samDesired : REGSAM;
      phkResult  : PHKEY) return LONG;
   pragma Import (Stdcall, RegOpenKeyEx, "RegOpenKeyExA");

   function RegQueryValueEx
     (Key         : HKEY;
      lpValueName : Address;
      lpReserved  : LPDWORD;
      lpType      : LPDWORD;
      lpData      : Address;
      lpcbData    : LPDWORD) return LONG;
   pragma Import (Stdcall, RegQueryValueEx, "RegQueryValueExA");

   function RegSetValueEx
     (Key         : HKEY;
      lpValueName : Address;
      Reserved    : DWORD;
      dwType      : DWORD;
      lpData      : Address;
      cbData      : DWORD) return LONG;
   pragma Import (Stdcall, RegSetValueEx, "RegSetValueExA");

   function RegEnumKey
     (Key         : HKEY;
      dwIndex     : DWORD;
      lpName      : Address;
      cchName     : DWORD) return LONG;
   pragma Import (Stdcall, RegEnumKey, "RegEnumKeyA");

   ---------------------
   -- Local Constants --
   ---------------------

   Max_Key_Size : constant := 1_024;
   --  Maximum number of characters for a registry key

   Max_Value_Size : constant := 2_048;
   --  Maximum number of characters for a key's value

   -----------------------
   -- Local Subprograms --
   -----------------------

   function To_C_Mode (Mode : Key_Mode) return REGSAM;
   --  Returns the Win32 mode value for the Key_Mode value

   procedure Check_Result (Result : LONG; Message : String);
   --  Checks value Result and raise the exception Registry_Error if it is not
   --  equal to ERROR_SUCCESS. Message and the error value (Result) is added
   --  to the exception message.

   ------------------
   -- Check_Result --
   ------------------

   procedure Check_Result (Result : LONG; Message : String) is
      use type LONG;
   begin
      if Result /= ERROR_SUCCESS then
         raise Registry_Error with
           Message & " (" & LONG'Image (Result) & ')';
      end if;
   end Check_Result;

   ---------------
   -- Close_Key --
   ---------------

   procedure Close_Key (Key : HKEY) is
      Result : LONG;
   begin
      Result := RegCloseKey (Key);
      Check_Result (Result, "Close_Key");
   end Close_Key;

   ----------------
   -- Create_Key --
   ----------------

   function Create_Key
     (From_Key : HKEY;
      Sub_Key  : String;
      Mode     : Key_Mode := Read_Write) return HKEY
   is
      REG_OPTION_NON_VOLATILE : constant := 16#0#;

      C_Sub_Key : constant String := Sub_Key & ASCII.NUL;
      C_Class   : constant String := "" & ASCII.NUL;
      C_Mode    : constant REGSAM := To_C_Mode (Mode);

      New_Key : aliased HKEY;
      Result  : LONG;
      Dispos  : aliased DWORD;

   begin
      Result :=
        RegCreateKeyEx
          (From_Key,
           C_Sub_Key (C_Sub_Key'First)'Address,
           0,
           C_Class (C_Class'First)'Address,
           REG_OPTION_NON_VOLATILE,
           C_Mode,
           Null_Address,
           New_Key'Unchecked_Access,
           Dispos'Unchecked_Access);

      Check_Result (Result, "Create_Key " & Sub_Key);
      return New_Key;
   end Create_Key;

   ----------------
   -- Delete_Key --
   ----------------

   procedure Delete_Key (From_Key : HKEY; Sub_Key : String) is
      C_Sub_Key : constant String := Sub_Key & ASCII.NUL;
      Result    : LONG;
   begin
      Result := RegDeleteKey (From_Key, C_Sub_Key (C_Sub_Key'First)'Address);
      Check_Result (Result, "Delete_Key " & Sub_Key);
   end Delete_Key;

   ------------------
   -- Delete_Value --
   ------------------

   procedure Delete_Value (From_Key : HKEY; Sub_Key : String) is
      C_Sub_Key : constant String := Sub_Key & ASCII.NUL;
      Result    : LONG;
   begin
      Result := RegDeleteValue (From_Key, C_Sub_Key (C_Sub_Key'First)'Address);
      Check_Result (Result, "Delete_Value " & Sub_Key);
   end Delete_Value;

   -------------------
   -- For_Every_Key --
   -------------------

   procedure For_Every_Key
     (From_Key  : HKEY;
      Recursive : Boolean := False)
   is
      procedure Recursive_For_Every_Key
        (From_Key  : HKEY;
         Recursive : Boolean := False;
         Quit      : in out Boolean);

      -----------------------------
      -- Recursive_For_Every_Key --
      -----------------------------

      procedure Recursive_For_Every_Key
        (From_Key : HKEY;
         Recursive : Boolean := False;
         Quit      : in out Boolean)
      is
         use type LONG;
         use type ULONG;

         Index  : ULONG := 0;
         Result : LONG;

         Sub_Key : Interfaces.C.char_array (1 .. Max_Key_Size);
         pragma Warnings (Off, Sub_Key);

         Size_Sub_Key : aliased ULONG;
         Sub_Hkey     : HKEY;

         function Current_Name return String;

         ------------------
         -- Current_Name --
         ------------------

         function Current_Name return String is
         begin
            return Interfaces.C.To_Ada (Sub_Key);
         end Current_Name;

      --  Start of processing for Recursive_For_Every_Key

      begin
         loop
            Size_Sub_Key := Sub_Key'Length;

            Result :=
              RegEnumKey
                (From_Key, Index, Sub_Key (1)'Address, Size_Sub_Key);

            exit when not (Result = ERROR_SUCCESS);

            Sub_Hkey := Open_Key (From_Key, Interfaces.C.To_Ada (Sub_Key));

            Action (Natural (Index) + 1, Sub_Hkey, Current_Name, Quit);

            if not Quit and then Recursive then
               Recursive_For_Every_Key (Sub_Hkey, True, Quit);
            end if;

            Close_Key (Sub_Hkey);

            exit when Quit;

            Index := Index + 1;
         end loop;
      end Recursive_For_Every_Key;

      --  Local Variables

      Quit : Boolean := False;

   --  Start of processing for For_Every_Key

   begin
      Recursive_For_Every_Key (From_Key, Recursive, Quit);
   end For_Every_Key;

   -------------------------
   -- For_Every_Key_Value --
   -------------------------

   procedure For_Every_Key_Value
     (From_Key : HKEY;
      Expand   : Boolean := False)
   is
      use GNAT.Directory_Operations;
      use type LONG;
      use type ULONG;

      Index  : ULONG := 0;
      Result : LONG;

      Sub_Key : String (1 .. Max_Key_Size);
      pragma Warnings (Off, Sub_Key);

      Value : String (1 .. Max_Value_Size);
      pragma Warnings (Off, Value);

      Size_Sub_Key : aliased ULONG;
      Size_Value   : aliased ULONG;
      Type_Sub_Key : aliased DWORD;

      Quit : Boolean;

   begin
      loop
         Size_Sub_Key := Sub_Key'Length;
         Size_Value   := Value'Length;

         Result :=
           RegEnumValue
             (From_Key, Index,
              Sub_Key (1)'Address,
              Size_Sub_Key'Unchecked_Access,
              null,
              Type_Sub_Key'Unchecked_Access,
              Value (1)'Address,
              Size_Value'Unchecked_Access);

         exit when not (Result = ERROR_SUCCESS);

         Quit := False;

         if Type_Sub_Key = REG_EXPAND_SZ and then Expand then
            Action
              (Natural (Index) + 1,
               Sub_Key (1 .. Integer (Size_Sub_Key)),
               Directory_Operations.Expand_Path
                 (Value (1 .. Integer (Size_Value) - 1),
                  Directory_Operations.DOS),
               Quit);

         elsif Type_Sub_Key = REG_SZ or else Type_Sub_Key = REG_EXPAND_SZ then
            Action
              (Natural (Index) + 1,
               Sub_Key (1 .. Integer (Size_Sub_Key)),
               Value (1 .. Integer (Size_Value) - 1),
               Quit);
         end if;

         exit when Quit;

         Index := Index + 1;
      end loop;
   end For_Every_Key_Value;

   ----------------
   -- Key_Exists --
   ----------------

   function Key_Exists
     (From_Key : HKEY;
      Sub_Key  : String) return Boolean
   is
      New_Key : HKEY;

   begin
      New_Key := Open_Key (From_Key, Sub_Key);
      Close_Key (New_Key);

      --  We have been able to open the key so it exists

      return True;

   exception
      when Registry_Error =>

         --  An error occurred, the key was not found

         return False;
   end Key_Exists;

   --------------
   -- Open_Key --
   --------------

   function Open_Key
     (From_Key : HKEY;
      Sub_Key  : String;
      Mode     : Key_Mode := Read_Only) return HKEY
   is
      C_Sub_Key : constant String := Sub_Key & ASCII.NUL;
      C_Mode    : constant REGSAM := To_C_Mode (Mode);

      New_Key : aliased HKEY;
      Result  : LONG;

   begin
      Result :=
        RegOpenKeyEx
          (From_Key,
           C_Sub_Key (C_Sub_Key'First)'Address,
           0,
           C_Mode,
           New_Key'Unchecked_Access);

      Check_Result (Result, "Open_Key " & Sub_Key);
      return New_Key;
   end Open_Key;

   -----------------
   -- Query_Value --
   -----------------

   function Query_Value
     (From_Key : HKEY;
      Sub_Key  : String;
      Expand   : Boolean := False) return String
   is
      use GNAT.Directory_Operations;
      use type ULONG;

      Value : String (1 .. Max_Value_Size);
      pragma Warnings (Off, Value);

      Size_Value : aliased ULONG;
      Type_Value : aliased DWORD;

      C_Sub_Key : constant String := Sub_Key & ASCII.NUL;
      Result    : LONG;

   begin
      Size_Value := Value'Length;

      Result :=
        RegQueryValueEx
          (From_Key,
           C_Sub_Key (C_Sub_Key'First)'Address,
           null,
           Type_Value'Unchecked_Access,
           Value (Value'First)'Address,
           Size_Value'Unchecked_Access);

      Check_Result (Result, "Query_Value " & Sub_Key & " key");

      if Type_Value = REG_EXPAND_SZ and then Expand then
         return Directory_Operations.Expand_Path
           (Value (1 .. Integer (Size_Value - 1)),
            Directory_Operations.DOS);
      else
         return Value (1 .. Integer (Size_Value - 1));
      end if;
   end Query_Value;

   ---------------
   -- Set_Value --
   ---------------

   procedure Set_Value
      (From_Key : HKEY;
       Sub_Key  : String;
       Value    : String;
       Expand   : Boolean := False)
   is
      C_Sub_Key : constant String := Sub_Key & ASCII.NUL;
      C_Value   : constant String := Value & ASCII.NUL;

      Value_Type : DWORD;
      Result     : LONG;

   begin
      Value_Type := (if Expand then REG_EXPAND_SZ else REG_SZ);

      Result :=
        RegSetValueEx
          (From_Key,
           C_Sub_Key (C_Sub_Key'First)'Address,
           0,
           Value_Type,
           C_Value (C_Value'First)'Address,
           C_Value'Length);

      Check_Result (Result, "Set_Value " & Sub_Key & " key");
   end Set_Value;

   ---------------
   -- To_C_Mode --
   ---------------

   function To_C_Mode (Mode : Key_Mode) return REGSAM is
      use type REGSAM;

      KEY_READ        : constant := 16#20019#;
      KEY_WRITE       : constant := 16#20006#;
      KEY_WOW64_64KEY : constant := 16#00100#;
      KEY_WOW64_32KEY : constant := 16#00200#;

   begin
      case Mode is
         when Read_Only =>
            return KEY_READ + KEY_WOW64_32KEY;

         when Read_Write =>
            return KEY_READ + KEY_WRITE + KEY_WOW64_32KEY;

         when Read_Only_64 =>
            return KEY_READ + KEY_WOW64_64KEY;

         when Read_Write_64 =>
            return KEY_READ + KEY_WRITE + KEY_WOW64_64KEY;
      end case;
   end To_C_Mode;

end GNAT.Registry;
