(******************************************************************************
 *                                                                            *
 *  Project: -                                                                *
 *           [Description]                                                    *
 *  File   : MpuRegistry ()                                                   *
 *           This class provides methodes for working with the                *
 *           Registry.                                                        *
 *                                                                            *
 *  Copyright (c) Michael Puff  http://www.michael-puff.de                    *
 *                                                                            *
 ******************************************************************************)

    (************************************************************************
     *                                                                      *
     *                        COPYRIGHT NOTICE                              *
     *                                                                      *
     * Copyright (c) 2001-2006, Michael Puff ["copyright holder(s)"]        *
     * All rights reserved.                                                 *
     *                                                                      *
     * Redistribution and use in source and binary forms, with or without   *
     * modification, are permitted provided that the following conditions   *
     * are met:                                                             *
     *                                                                      *
     * 1. Redistributions of source code must retain the above copyright    *
     *    notice, this list of conditions and the following disclaimer.     *
     * 2. Redistributions in binary form must reproduce the above copyright *
     *    notice, this list of conditions and the following disclaimer in   *
     *    the documentation and/or other materials provided with the        *
     *    distribution.                                                     *
     * 3. The name(s) of the copyright holder(s) may not be used to endorse *
     *    or promote products derived from this software without specific   *
     *    prior written permission.                                         *
     *                                                                      *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  *
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    *
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    *
     * FORA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE        *
     * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          *
     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
     * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;     *
     * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER     *
     * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT   *
     * LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY *
     * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          *
     * POSSIBILITY OF SUCH DAMAGE.                                          *
     *                                                                      *
     ************************************************************************)

unit MpuRegistry;

interface

uses
  windows;

type
  TMpuRegistry = class(TObject)
  private
    FhkResult: HKEY;
    FMachine: PWideChar;
    FhKey: HKEY;
    function GetMachine: WideString;
    function GetHKey: HKEY;
  public
    constructor Create(const Machine: string; hKey: HKEY);
    constructor CreateW(const Machine: WideString; hKey: HKEY);
    destructor Destroy; override;
    function Connect: LongInt;
    function CreateKey(Root: HKEY; const SubKey: string): LongInt;
    function CreateKeyW(Root: HKEY; const SubKey: WideString): LongInt;
    function OpenKey(const SubKey: string; samDesired: REGSAM): LongInt;
    function OpenKeyW(const SubKey: WideString; samDesired: REGSAM): LongInt;
    function ReadInt(const ValueName: string; var Value: Integer): LongInt;
    function ReadIntW(const ValueName: WideString; var Value: Integer): LongInt;
    function ReadByte(const ValueName: string; var Value: Byte; default: Byte = 0):  LongInt;
    function ReadByteW(const ValueName: WideString; var Value: Byte; default: Byte = 0): LongInt;
    function ReadBool(const ValueName: string; var Value: Boolean; default: Boolean = True): LongInt;
    function ReadBoolW(const ValueName: string; var Value: Boolean; default: Boolean = True): LongInt;
    function ReadString(const ValueName: string; var Value: string): LongInt;
    function ReadStringW(const ValueName: WideString; var Value: WideString): LongInt;
    function WriteInt(const ValueName: string; Value: Integer): LongInt;
    function WriteIntW(const ValueName: WideString; Value: Integer): LongInt;
    function WriteByte(const ValueName: string; Value: Byte): LongInt;
    function WriteByteW(const ValueName: WideString; Value: Byte): LongInt;
    function WriteBool(const ValueName: string; Value: Boolean): LongInt;
    function WriteBoolW(const ValueName: WideString; Value: Boolean): LongInt;
    function WriteString(const ValueName: string; Value: string): LongInt;
    function WriteStringW(const ValueName: WideString; const Value: WideString): LongInt;
    function DeleteValueName(const ValueName: string): LongInt;
    function DeleteSubKey(const SubKey: string): LongInt;
    function DeleteTree(const SubKey: WideString): Longint;
    property Machine: WideString read GetMachine;
    property hKey: HKEY read GetHKey;
  end;

implementation

function SHDeleteKey(key: HKEY; SubKey: LPCWSTR): Integer; stdcall; external 'shlwapi.dll' name 'SHDeleteKeyW';

///// Constructor - Destructor /////////////////////////////////////////////////

constructor TMpuRegistry.Create(const Machine: string; hKey: HKEY);
begin
  Self.CreateW(Machine, hKey);
end;

constructor TMpuRegistry.CreateW(const Machine: WideString; hKey: HKEY);
begin
  inherited Create;
  FMachine := PWideChar(Machine);
  FhKey := hKey;
end;

destructor TMpuRegistry.Destroy;
begin
  RegCloseKey(FhkResult);
  inherited Destroy;
end;

////////////////////////////////////////////////////////////////////////////////

///// Methods //////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.Connect
//    Connects to the Registry using Machine and Root-Key.
//    Stores Regeistry Handle in FhkResult for further use

function TMpuRegistry.Connect: LongInt;
begin
  result := RegConnectRegistryW(FMachine, FhKey, FhkResult);
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.CreateKey
//    Creates a SubKey
//

function TMpuRegistry.CreateKey(Root: HKEY; const SubKey: string): LongInt;
begin
  result := CreateKeyW(Root, SubKey);
end;


function TMpuRegistry.CreateKeyW(Root: HKEY; const SubKey: WideString): LongInt;
begin
  result := RegCreateKeyExW(Root, PWideChar(SubKey), 0, nil,
    REG_OPTION_NON_VOLATILE, KEY_WRITE, nil, FhkResult, nil);
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.OpenKey
//    Opens the specified key with access rigths (KEY_READ, KEY_WRITE, ...)
//

function TMpuRegistry.OpenKey(const SubKey: string; samDesired: REGSAM):
  LongInt;
begin
  result := OpenKeyW(SubKey, samDesired);
end;

function TMpuRegistry.OpenKeyW(const SubKey: WideString; samDesired: REGSAM):
  LongInt;
begin
  result := RegOpenKeyExW(FhkResult, PWideChar(SubKey), 0, samDesired, FhkResult);
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.ReadInt
//    Reads an Interger from the Registry
//

function TMpuRegistry.ReadInt(const ValueName: string; var Value: Integer):
  LongInt;
begin
  result := ReadIntW(ValueName, Value);
end;

function TMpuRegistry.ReadIntW(const ValueName: WideString; var Value: Integer):
  LongInt;
var
  cbData: Integer;
  lpType: DWORD;
begin
  // get size of required data
  result := RegQueryValueExW(FhkResult, PWideChar(ValueName), nil, @lpType, @Value,
    @cbData);
  if cbData <> 0 then
  begin
    result := RegQueryValueExW(FhkResult, PWideChar(ValueName), nil, @lpType,
      @Value, @cbData);
  end;
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.ReadByte
//    Reads a Byte from the Registry
//

function TMpuRegistry.ReadByte(const ValueName: string; var Value: Byte;
  default: Byte = 0): LongInt;
begin
  result := ReadByteW(ValueName, Value, default);
end;

function TMpuRegistry.ReadByteW(const ValueName: WideString; var Value: Byte;
  default: Byte = 0): LongInt;
var
  temp: Integer;
begin
  result := ReadIntW(ValueName, temp);
  if Result = ERROR_SUCCESS then
    Value := Byte(temp)
  else
    Value := default;
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.ReadBool
//    Reads a Boolean from the Registry
//

function TMpuRegistry.ReadBool(const ValueName: string; var Value: Boolean;
  default: Boolean = True): LongInt;
begin
  Result := ReadBoolW(ValueName, Value, default);
end;

function TMpuRegistry.ReadBoolW(const ValueName: string; var Value: Boolean;
  default: Boolean = True): LongInt;
var
  temp: Integer;
begin
  Result := ReadIntW(ValueName, temp);
  if Result = ERROR_SUCCESS then
    Value := Boolean(temp)
  else
    Value := default;
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.ReadString
//    Reads a String from the Registry
//

function TMpuRegistry.ReadString(const ValueName: string; var Value: string):
  LongInt;
var
  cbData: Integer;
  lpType: DWORD;
  Buffer: PChar;
begin
  // get size of required data
  result := RegQueryValueEx(FhkResult, PChar(ValueName), nil, @lpType, nil,
    @cbData);
  if cbData <> 0 then
  begin
    GetMem(Buffer, cbData);
    try
      result := RegQueryValueEx(FhkResult, PChar(ValueName), nil, @lpType,
        Pointer(Buffer), @cbData);
      Value := Buffer; // <- hier AccessViolation
    finally
      FreeMem(Buffer);
    end;
  end;
end;

function TMpuRegistry.ReadStringW(const ValueName: WideString;
  var Value: WideString): LongInt;
var
  cbData: Integer;
  lpType: DWORD;
  Buffer: PWideChar;
begin
  // get size of required data
  result := RegQueryValueExW(FhkResult, PWideChar(ValueName), nil, @lpType, nil,
    @cbData);
  if cbData <> 0 then
  begin
    GetMem(Buffer, cbData);
    try
      result := RegQueryValueExW(FhkResult, PWideChar(ValueName), nil, @lpType,
        Pointer(Buffer), @cbData);
      Value := Buffer;
    finally
      FreeMem(Buffer);
    end;
  end;
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.WriteInt
//    Writes an Integer to the Registry
//

function TMpuRegistry.WriteInt(const ValueName: string; Value: Integer): LongInt;
begin
  result := WriteIntW(ValueName, Value);
end;

function TMpuRegistry.WriteIntW(const ValueName: WideString; Value: Integer): LongInt;
begin
  result := RegSetValueExW(FhkResult, PWideChar(ValueName), 0, REG_DWORD, @Value,
    sizeof(Integer));
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.WriteByte
//    Writes a Byte to the Registry
//

function TMpuRegistry.WriteByte(const ValueName: string; Value: Byte): LongInt;
begin
  result := WriteIntW(ValueName, Value);
end;

function TMpuRegistry.WriteByteW(const ValueName: WideString; Value: Byte): LongInt;
begin
  result := WriteIntW(ValueName, Value);
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.WriteBool
//    Writes a Boolean to the Registry
//

function TMpuRegistry.WriteBool(const ValueName: string; Value: Boolean): LongInt;
begin
  result := WriteInt(ValueName, ord(Value));
end;

function TMpuRegistry.WriteBoolW(const ValueName: WideString; Value: Boolean): LongInt;
begin
  result := WriteIntW(ValueName, ord(Value));
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.WriteString
//    Writes a String to the Registry
//

function TMpuRegistry.WriteString(const ValueName: string; Value: string):
  LongInt;
begin
  result := RegSetValueEx(FhkResult, PChar(ValueName), 0, REG_SZ,
    PChar(Value), length(Value));
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.WriteStringW
//    Writes a unicode string to the Registry
//    Autor: Manuel Pöter

function TMpuRegistry.WriteStringW(const ValueName: WideString; const Value: WideString):
  LongInt;
begin
  result := RegSetValueExW(FhkResult, PWideChar(ValueName), 0, REG_SZ,
    PWideChar(Value), (Length(Value) + 1) * SizeOf(WideChar));
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.DeleteValueName
//    Deletes a value from the Registry
//

function TMpuRegistry.DeleteValueName(const ValueName: string): LongInt;
begin
  result := RegDeleteValue(FhkResult, PChar(ValueName));
end;

////////////////////////////////////////////////////////////////////////////////
//
//  TMpuRegistry.DeleteSubKey
//    Deletes a SubKey from the Registry
//

function TMpuRegistry.DeleteSubKey(const SubKey: string): LongInt;
begin
  result := RegDeleteKey(FhkResult, PChar(SubKey));
end;

function TMpuRegistry.DeleteTree(const SubKey: WideString): LongInt;
begin
  result := SHDeleteKey(FhkResult, PWideChar(SubKey));
end;

////////////////////////////////////////////////////////////////////////////////

//// Propterties ///////////////////////////////////////////////////////////////

function TMpuRegistry.GetMachine: WideString;
begin
  result := FMachine;
end;

function TMpuRegistry.GetHKey: HKEY;
begin
  result := FhKey;
end;

////////////////////////////////////////////////////////////////////////////////

end.


