Solved

Edit Registry Code to show the whole key IE "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"

Posted on 2008-09-29
3
1,071 Views
Last Modified: 2012-06-21
The object here is to help show the exact  key and full path "IE"
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run  
I will except a demo that will watch the registry and show me this info or help fix the current code posted here to do so.
unit RegMonitorThread;
 
interface
 
uses
  Classes, Windows, Messages, Registry, SysUtils;
 
  const
  WM_REGCHANGE  = WM_USER + 1973;
 
//Need to redeclare the API function - instead of BOOL is uses DWORD.
function RegNotifyChangeKeyValue(       hKey: HKEY;
                                        bWatchSubtree: DWORD;
                                        dwNotifyFilter: DWORD;
                                        hEvent: THandle;
                                        fAsynchronus: DWORD): Longint; stdcall;
external 'advapi32.dll' name 'RegNotifyChangeKeyValue';
 
type
  TChangeData = record
    Key : string;
    RootKey : HKey;
  end;
 
  TRegMonitorThread = class(TThread)
 
  private
    FReg: TRegistry;
    fChangeData : TChangeData;
    fKey: string;
    fRootKey: HKey;
    fWatchSub: boolean;
    fFilter: integer;
    fWnd: THandle;
    id: integer;
    procedure InitThread;
    procedure SetFilter(const Value: integer);
    function GetFilter: integer;
    function GetChangeData: TChangeData;
 
  public
    constructor Create;
    destructor Destroy; override;
    property Key: string        read fKey       write fKey;
    property RootKey: HKey      read fRootKey   write fRootKey;
    property WatchSub: boolean  read fWatchSub  write fWatchSub;
    property Filter: integer    read GetFilter  write SetFilter;
    property Wnd: THandle       read fWnd       write fWnd;
    property i: integer    read id  write id;
    property ChangeData : TChangeData read GetChangeData;
 
  protected
    procedure Execute; override;
 
  end;
 
implementation
 
{ TRegMonitorThread }
constructor TRegMonitorThread.Create;
begin
  // Execute wont be called until after Resume is called.
  inherited Create(True);
 
  FReg := TRegistry.Create;
end;
 
destructor TRegMonitorThread.Destroy;
begin
  FReg.Free;
  inherited;
end;
 
procedure TRegMonitorThread.InitThread;
begin
  FReg.RootKey := RootKey;
  if not FReg.OpenKeyReadOnly(Key) then
        MessageBox(     fwnd  ,
                        'Error accesing key',
                        'GetLastError',
                        MB_OK or MB_ICONINFORMATION )
  else
        RegNotifyChangeKeyValue(FReg.CurrentKey, 1, Filter, Cardinal(0), Cardinal(False));
end;
 
 
procedure TRegMonitorThread.Execute;
var
        tmp : Integer;
begin
  InitThread;
 
  while not Terminated do
  begin
      fChangeData.RootKey := RootKey;
      fChangeData.Key := Key;
      SendMessage(Wnd, WM_REGCHANGE, i, LongInt(PChar(Key)));
 
      tmp := RegNotifyChangeKeyValue(    FReg.CurrentKey,
                                        1,
                                        Filter,
                                        Cardinal(0),
                                        Cardinal(0));
      if tmp <> ERROR_SUCCESS then
      begin
                // Display the string.
        MessageBox(     fwnd,
                        'Error accesing key',
                        'GetLastError',
                        MB_OK or MB_ICONINFORMATION );
        fChangeData.RootKey := 0;
        fChangeData.Key := 'Terminated due to missing key.';
        SendMessage(Wnd, WM_REGCHANGE, i, LongInt(PChar(Key)));
        self.Terminate;
       end;
  end;
end;
 
 
 
procedure TRegMonitorThread.SetFilter(const Value: integer);
begin
  if fFilter <> Value then
  begin
    fFilter := Value;
  end;
end;
 
 
function TRegMonitorThread.GetFilter: integer;
begin
  if fFilter = 0 then begin
    fFilter:=
      REG_NOTIFY_CHANGE_NAME or
      REG_NOTIFY_CHANGE_ATTRIBUTES or
      REG_NOTIFY_CHANGE_LAST_SET or
      REG_NOTIFY_CHANGE_SECURITY;
  end;
  Result := fFilter;
end;
 
 
function TRegMonitorThread.GetChangeData: TChangeData;
begin
  Result := fChangeData;
end;
 
end.
 
 
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<FOrm1Code>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, RegMonitorThread, MPlayer;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    Memo3: TMemo;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    Memo4: TMemo;
    Memo5: TMemo;
    Edit5: TEdit;
    CheckBox5: TCheckBox;
    soundPlayer1: TMediaPlayer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure CheckBox3Click(Sender: TObject);
    procedure CheckBox2Click(Sender: TObject);
    procedure CheckBox4Click(Sender: TObject);
    procedure CheckBox5Click(Sender: TObject);
  private
    soundAvailable : BOOL;
    procedure WMREGCHANGE(var Msg : TMessage); message WM_REGCHANGE;
    procedure initSound;
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  RegMonitorThread1 : TRegMonitorThread;
  RegMonitorThread2 : TRegMonitorThread;
  RegMonitorThread3 : TRegMonitorThread;
  RegMonitorThread4 : TRegMonitorThread;
  RegMonitorThread5 : TRegMonitorThread;
  
implementation
 
 
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
begin
        RegMonitorThread1 := TRegMonitorThread.Create;	//We create one thread per key to watch
        RegMonitorThread2 := TRegMonitorThread.Create;
        RegMonitorThread3 := TRegMonitorThread.Create;
        RegMonitorThread4 := TRegMonitorThread.Create;
        RegMonitorThread5 := TRegMonitorThread.Create;
 
  with RegMonitorThread1 do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '';
    RootKey := HKEY_CLASSES_ROOT ;
        i := 1;		// thread id
    WatchSub := True;
//    Resume;		Start only when signaled to do so
  end;
 
  with RegMonitorThread2 do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '';
    RootKey := HKEY_CURRENT_USER ;
        i := 2;
    WatchSub := True;
  end;
 
  with RegMonitorThread3 do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '';
    RootKey := HKEY_LOCAL_MACHINE ;
        i := 3;
    WatchSub := True;
  end;
 
  with RegMonitorThread4 do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '';
    RootKey := HKEY_USERS ;
        i := 4;
    WatchSub := True;
  end;
 
  with RegMonitorThread5 do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '';
    RootKey := HKEY_CURRENT_CONFIG ;
        i := 5;
    WatchSub := True;
  end;
 
    initSound;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
        RegMonitorThread1.Terminate;
        RegMonitorThread2.Terminate;
        RegMonitorThread3.Terminate;
        RegMonitorThread4.Terminate;
        RegMonitorThread5.Terminate;
        if soundAvailable then	//if we were able to open the sound file
            soundPlayer1.Close;
end;
 
procedure TForm1.WMREGCHANGE(var Msg: TMessage);	//we put presentation code here
begin
 
        if Msg.WParam = 1 then
        begin
                Memo1.Lines.Add('-------------------------------------------');
                Memo1.Lines.Add('Registry change at ' + DateTimeToStr(Now));
                Memo1.Lines.Add(IntToStr(RegMonitorThread1.ChangeData.RootKey) +
                  ' - ' + RegMonitorThread1.ChangeData.Key);
        end
        else if Msg.WParam = 2 then
        begin
                Memo2.Lines.Add('-------------------------------------------');
                Memo2.Lines.Add('Registry change at ' + DateTimeToStr(Now));
                Memo2.Lines.Add(IntToStr(RegMonitorThread2.ChangeData.RootKey) +
                  ' - ' + RegMonitorThread2.ChangeData.Key);
        end
        else if Msg.WParam = 3 then
        begin
                Memo3.Lines.Add('-------------------------------------------');
                Memo3.Lines.Add('Registry change at ' + DateTimeToStr(Now));
                Memo3.Lines.Add(IntToStr(RegMonitorThread3.ChangeData.RootKey) +
                  ' - ' + RegMonitorThread3.ChangeData.Key);
        end
        else if Msg.WParam = 4 then
        begin
                Memo4.Lines.Add('-------------------------------------------');
                Memo4.Lines.Add('Registry change at ' + DateTimeToStr(Now));
                Memo4.Lines.Add(IntToStr(RegMonitorThread4.ChangeData.RootKey) +
                  ' - ' + RegMonitorThread4.ChangeData.Key);
        end
        else if Msg.WParam = 5 then
        begin
                Memo5.Lines.Add('-------------------------------------------');
                Memo5.Lines.Add('Registry change at ' + DateTimeToStr(Now));
                Memo5.Lines.Add(IntToStr(RegMonitorThread5.ChangeData.RootKey) +
                  ' - ' + RegMonitorThread5.ChangeData.Key);
        end;
        if soundAvailable then
            soundPlayer1.Play;
end;
 
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
        if not CheckBox1.Checked then
        begin
            Edit1.Enabled := True;
            Edit1.Color := clWindow;
            TerminateThread(RegMonitorThread1.Handle,0);	//Stop the thread
        end
        else
        begin
            RegMonitorThread1 := TRegMonitorThread.Create;
            Edit1.Enabled := False;				//Run the thread again
            Edit1.Color := clInactiveCaptionText;
            with RegMonitorThread1 do
            begin
                FreeOnTerminate:=True;			// I know this code is repeated
                Wnd := Form1.Handle;			// I am leaving it so you can understand
                Key := Edit1.Text;			//everything. 
                RootKey := HKEY_CLASSES_ROOT ;
                i := 1;
                WatchSub := True;
                Resume;
            end;
        end;
end;
procedure TForm1.CheckBox2Click(Sender: TObject);
begin
        if not CheckBox2.Checked then
        begin
            Edit2.Enabled := True;
            Edit2.Color := clWindow;
            TerminateThread(RegMonitorThread2.Handle,0);
        end
        else
        begin
            RegMonitorThread2 := TRegMonitorThread.Create;
            Edit2.Enabled := False;
            Edit2.Color := clInactiveCaptionText;
            with RegMonitorThread2 do
            begin
                FreeOnTerminate:=True;
                Wnd := Form1.Handle;
                Key := Edit2.Text;
                RootKey := HKEY_CURRENT_USER ;
                i := 2;
                WatchSub := True;
                Resume;
            end;
        end;
end;
procedure TForm1.CheckBox3Click(Sender: TObject);
begin
        if not CheckBox3.Checked then
        begin
            Edit3.Enabled := True;
            Edit3.Color := clWindow;
            TerminateThread(RegMonitorThread3.Handle,0);
        end
        else
        begin
            RegMonitorThread3 := TRegMonitorThread.Create;
            Edit3.Enabled := False;
            Edit3.Color := clInactiveCaptionText;
            with RegMonitorThread3 do
            begin
                FreeOnTerminate:=True;
                Wnd := Form1.Handle;
                Key := Edit3.Text;
                RootKey := HKEY_LOCAL_MACHINE ;
                i := 3;
                WatchSub := True;
                Resume;
            end;
        end;
end;
procedure TForm1.CheckBox4Click(Sender: TObject);
begin
        if not CheckBox4.Checked then
        begin
            Edit4.Enabled := True;
            Edit4.Color := clWindow;
            TerminateThread(RegMonitorThread4.Handle,0);
        end
        else
        begin
            RegMonitorThread4 := TRegMonitorThread.Create;
            Edit4.Enabled := False;
            Edit4.Color := clInactiveCaptionText;
            with RegMonitorThread4 do
            begin
                FreeOnTerminate:=True;
                Wnd := Form1.Handle;
                Key := Edit4.Text;
                RootKey := HKEY_USERS;
                i := 4;
                WatchSub := True;
                Resume;
            end;
        end;
end;
 
procedure TForm1.CheckBox5Click(Sender: TObject);
begin
        if not CheckBox5.Checked then
        begin
            Edit5.Enabled := True;
            Edit5.Color := clWindow;
            TerminateThread(RegMonitorThread5.Handle,0);
        end
        else
        begin
            RegMonitorThread5 := TRegMonitorThread.Create;
            Edit5.Enabled := False;
            Edit5.Color := clInactiveCaptionText;
            with RegMonitorThread5 do
            begin
                FreeOnTerminate:=True;
                Wnd := Form1.Handle;
                Key := Edit5.Text;
                RootKey := HKEY_CURRENT_CONFIG;
                i := 5;
                WatchSub := True;
                Resume;
            end;
        end;
end;
 
procedure TForm1.initSound();
var sWinDir: String;
    iLength: Integer;
begin
 
    iLength := 255;
    setLength(sWinDir, iLength);
    iLength := GetWindowsDirectory(PChar(sWinDir), iLength);
    setLength(sWinDir, iLength);
 
    With soundPlayer1 do
    begin
         Filename := sWinDir + '\media\notify.wav'; //specify sound file
         try
            Open;	// this throws and exception. must catch it.
         except
            on EMCIDeviceError do ShowMessage('Could not open sound file');
         end;
         if Error = 0 then
            soundAvailable := True	//flag for use
         else
            soundAvailable := False;
    end;
end;
 
 
end.

Open in new window

0
Comment
Question by:Grant Fullen
  • 2
3 Comments
 
LVL 21

Accepted Solution

by:
ziolko earned 150 total points
ID: 22602995
not possible. RegNotifyChangeKeyValue signals only that change was made in specified registry key (or it's sub key if bWatchSubtree is true). there's no indication which values has been changed

ziolko.
0
 
LVL 21

Expert Comment

by:ziolko
ID: 22603025
... of course you can backup whole registry key to file set notification, once you get notification backup registry again and compare changes. but if you set notifications on all root keys this method will most likely completely kill preformance of your machine

ziolko.
0
 
LVL 26

Assisted Solution

by:EddieShipman
EddieShipman earned 100 total points
ID: 24310885
Per KB Q236570: http://support.microsoft.com/kb/236570

"As with the file change notification APIs, RegNotifyChangeKeyValue() does not return any indication as to what has changed in the registry key or its subkeys or values. The program must know the state of the keys or values prior to the notification, so that it can determine what has changed. "
0

Featured Post

Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
code issue 8 131
Using idhttp to login to instagram 2 90
Delphi Yen format 3 35
Delphi: barcode reading on android platform 1 30
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question