Solved

Keyboard and Mouse Hook

Posted on 2010-08-31
37
676 Views
Last Modified: 2012-06-27
I am discourage using wh_cbt because it does not get none-window and console program, because of that,  I'd like a code for Keyboard and Mouse Hook to get the path and filename before launching it, using mouse down, and arrow up,down,left,right.
0
Comment
Question by:systan
  • 23
  • 13
37 Comments
 
LVL 13

Accepted Solution

by:
aflarin earned 500 total points
Comment Utility
Here is the link to mouse and keyboard hooks:

http://delphi.about.com/od/windowsshellapi/a/keyboard_hook.htm
http://delphi.about.com/od/windowsshellapi/a/mousehook.htm

But I don't think these hooks can help you to intercept launch event. How are you going to do that?
0
 
LVL 14

Author Comment

by:systan
Comment Utility
Ok;
When you mouse down clicked a filename, the hook will get the mouse down clicked highlighten text.

When the arrows move and a text is highlighten, the hook will get the text.

Ok;
If my procedure is wrong getting the filename before launched, then I should use zwCreateSection, but its to impossible to do that,  I've written that code "zwcreatesection prozy" but filename is null during a sendmessage to my form and I don't know how to pause the createdsection.

So, any advices how to get the filename, including the non-window and console? keyboard and mouse?
0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
>> When you mouse down clicked a filename, the hook will get the mouse down clicked highlighten text.
>> When the arrows move

Are you going to try check if the highlighted text is .exe file?
And what?
What if it is just Word and I just write about MyProject.exe?

>> So, any advices how to get the filename, including the non-window and console? keyboard and mouse?

Filename of what? of process? ok, but which process? do you know its handle or process id?
0
 
LVL 14

Author Comment

by:systan
Comment Utility
>>Filename of what? of process? ok, but which process? do you know its handle or process id?
Ok;
Filename of the file itself, Aflarin do you remember getting the filename with the wh_cbt? but it doesn't get the filename if none-window and console program.

So, getting the none-window and console is impossible with setwindowsEX?  as you said that.
The process of launching the file is not a concern on this question,   gettting the highlighten text during a mouse down or keyboard move is what I am asking if it is possible.
Because when I get the path and filename during a key and mouse hook, I will read the file if is good or not,  if is bad I will lock the file, so launching it, is impossible,  and if is good it will continue to launch.

Aflarin if you have another idea of getting the path and filename before it is launch? please provide your solution.   And as you know mostly of my pesonal projects are solved by you, and it might be you can solve this one.

Thank you
0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
oh Systan..  you so kind :) Thanks for good words

>> gettting the highlighten text during a mouse down or keyboard move is what I am asking if it is possible.

I think it is possible. It's hard but possible. And it will take a lot of time...
You can easy do the hook for mouse and keyboard events. That's not a problem. But highlighted text... It may be highlighted into edit control, into list, into combo, into listview, into treeview or event in custom control.

A lot of work, but...
>> Because when I get the path and filename during a key and mouse hook, I will read the file if is good

What if user just click on button to launch other app? There is no any highlighted text then.
What if other app will be launched automatically by Windows when new USB disk (or DVD) is inserted?

>> Aflarin if you have another idea of getting the path and filename before it is launch?

In one of your previous questions I posted all ways how to get it. If you will find another way and it will really work - it will be interesting for me
0
 
LVL 14

Author Comment

by:systan
Comment Utility
Ok;
>>What if user just click on button to launch other app? There is no any highlighted text then.?
Wise question,  but as I understand this?  theres no need for this because the person knows whats going on the button box.

>>What if other app will be launched automatically by Windows when new USB disk (or DVD) is inserted?
Actually I get the app by zwOpenFiles and analyze them after it has been launch.
with this code;

function NewZwOpenFile(OUT FileHandle:PHANDLE;
    const DesiredAccess:ACCESS_MASK;
    const ObjectAttributes:PObjectAttributes;
    OUT IoStatusBlock:PIO_STATUS_BLOCK;
    const ShareAccess,
          OpenOptions:ULONG):NTStatus;
    stdcall;
var
    s:string;
begin
 s:=WideCharToString(ObjectAttributes^.ObjectName^.Buffer);
 SendMessage(FindWindowEx(FindWindow('TTTForm', nil), 0, 'TListBox', nil), LB_INSERTSTRING, 0, Integer(PChar(s)));
result:=TrueZwOpenFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,ShareAccess,OpenOptions);
end;

After analyzing the file has a bad works, listen another file if is bad also, and if is bad, list it in bad list for quarantine.


>>In one of your previous questions I posted all ways how to get it.
Yes, but a problem when launching a console and non-window program.

>>If you will find another way and it will really work - it will be interesting for me
Aflarin your always interested because you know what you really are in delphi zone

Ok; leaving the key and mouse hook, if thats your option, because its hard and time consuming.

Actually I have a code researched that gets a created file, but I nothing to add because I am not capable of understanding the procedures of getting the created file before launch.
This is the code; link;

http://slow.alfamoon.com/sources/process_seeker.dpr

http://slow.alfamoon.com/sources/file_seeker.dpr



I hope with that code, you can add something to really get the path and name before launching.  If is possible, and maybe not.

Open in new window

0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
I don't understand something. You said you hook ZwOpenFile and it works. So this way should intercept any file opened at pc (even console and non-window app).

Why are you looking for other way?
0
 
LVL 14

Author Comment

by:systan
Comment Utility
>>I don't understand something. You said you hook ZwOpenFile and it works.
Yes, it works also in ZwCreateFiles, as youve mention I did proxy it.

>>So this way should intercept any file opened at pc (even console and non-window app).
Yes, I did intercept the files (even console and non-window app).   But just throwing the string to my form.

>>Why are you looking for other way?
And I can't do like you did,  as it will pause and wait for the user to select yes or no.

OR maybe your asking "Why are you looking for other way?"
because of this link?
http://slow.alfamoon.com/sources/process_seeker.dpr

Because that link does not need to be a dll to get the created process.

Oh, as you said that;
//======
but as far as I know there are the following ways to do what you want:

1a. SetWindowHooks (CBT , WinProc or WinProcRet) to intercept the window creation notification, then you can get the window process and check if it's a new process
If you want to forbid launching some application, you can try to terminate it after get notification, but it may fail if the app was launched with non default rights or if you app was launched with limited rights

Pros: it's rather simple way
Cons: it won't work with no-window applications and with console applications (I'm not sure about console application, but as far as I remember you don't receive the window creation notification for console windows). Also ProcessTerminate may fail

1b. SetWinEventHook

Pros: the same as 1a, but you can intercept the window creation notification in the exe file and get rif of the dll
Cons: the same as 1a
//======


And why this code gets a non-window and console?
Library xxx;

...

...

...

Procedure SetHook();

var

 Bytes: dword;

begin

  PtrZwq  := GetProcAddress(GetModuleHandle('ntdll.dll'),'ZwOpenFile');

  ReadProcessMemory(INVALID_HANDLE_VALUE, PtrZwq, @OldZwq, SizeOf(OldCode), Bytes);

  JmpZwq.PuhsOp  := $68;

  JmpZwq.PushArg := @NewZwOpenFile;

  JmpZwq.RetOp   := $C3;

  WriteProcessMemory(INVALID_HANDLE_VALUE, PtrZwq, @JmpZwq, SizeOf(far_jmp), Bytes);

end;



Procedure Unhook();

var

 Bytes: dword;

begin

  WriteProcessMemory(INVALID_HANDLE_VALUE, PtrZwq, @OldZwq, SizeOf(OldCode), Bytes);

end;



// ??????

Function MessageProc(code : integer; wParam : word;

                    lParam : longint) : longint; stdcall;

begin

 CallNextHookEx(0, Code, wParam, lparam);

 Result := 0;

end;



Procedure SetGlobalHookProc();

begin



 SETWINDOWSHOOKEx (WH_GETMESSAGE, @MessageProc, HInstance, 0);

 Sleep(INFINITE);



end;

//



Procedure SetGlobalHook();

var

 hMutex: dword;

 TrId: dword;

begin

 hMutex := CreateMutex(nil, false, 'ScanerHook');

 if GetLastError = 0 then

 CreateThread(nil, 0, @SetGlobalHookProc, nil, 0, TrId) else

 CloseHandle(hMutex);

end;



procedure DLLEntryPoint(dwReason: DWord);

begin

  case dwReason of

    DLL_PROCESS_ATTACH: begin

                          SetGlobalHook();

                          SetHook();

                        end;

    DLL_PROCESS_DETACH: begin

                          Unhook();

                        end;

  end;

end;





begin

 DllProc := @DLLEntryPoint;

 DLLEntryPoint(DLL_PROCESS_ATTACH);

end.







What about the using WH_GETMESSAGE, maybe that will solved.

Anyway, do you have any solution to get what I want?

Open in new window

0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
>> Yes, I did intercept the files (even console and non-window app).   But just throwing the string to my form.
>> And I can't do like you did,  as it will pause and wait for the user to select yes or no.

Why you can't do that? check the result that SendMessage returns and then return error status without calling TrueZwOpenFile. Something like

const
  YOUR_SIGN_THAT_YOU_DECLINE_OPENING = 1;
...
 if SendMessage(FindWindowEx(FindWindow('TTTForm', nil), 0, 'TListBox', nil), LB_INSERTSTRING, 0, Integer(PChar(s))) = YOUR_SIGN_THAT_YOU_DECLINE_OPENING then
   Result:= STATUS_INTERNAL_ERROR
else
  result:=TrueZwOpenFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,ShareAccess,OpenOptions);
end;

>> http://slow.alfamoon.com/sources/process_seeker.dpr

This code just monitors the handle table of processes. It likes you will get process list into OnTimer proc and compare it with the previous process list.

>> And why this code gets a non-window and console?

because it's not 1a way - you use SetWindowsHook only for injecting your dll to all processes, not for intercepting process creation. It is a half of ZwOpenFile way :) The half - because you intercept ZwOpenFile in the user mode and I believe that it don't intercept all files
0
 
LVL 14

Author Comment

by:systan
Comment Utility
Ok;
>>
if SendMessage(FindWindowEx(FindWindow('TTTForm', nil), 0, 'TListBox', nil), LB_INSERTSTRING, 0, Integer(PChar(s))) = YOUR_SIGN_THAT_YOU_DECLINE_OPENING then
   Result:= STATUS_INTERNAL_ERROR
else
  result:=TrueZwOpenFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,ShareAccess,OpenOptions);
end;


That is not the procedure,  this will not do like you did.
Here's the complete code with pas and dfm, let me see if got it.
libxxx.zip
0
 
LVL 14

Author Comment

by:systan
Comment Utility
Aflarin;
You can send the zip to my mail if you want

Thanks
0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
I've changed only a few lines:
Unit1.pas



  TForm1 = class(TForm)

  ...

  private

    // added

    procedure WMCopyData(var AMsg: TWMCopyData); message WM_COPYDATA; 

....



procedure TForm1.WMCopyData(var AMsg: TWMCopyData);

var

  processName: AnsiString;

begin

  AMsg.Result:= 0;

  processName:= Copy(PAnsiChar(AMsg.CopyDataStruct.lpData), 0, AMsg.CopyDataStruct.cbData);

  if (MessageDlg( Format('Process (id=%d) is trying to open file %s with %x access rights. They include FILE_EXECUTE flag, so file may be executed. Would you like to forbid it?', [AMsg.From, processName, AMsg.CopyDataStruct.dwData]), mtConfirmation, [mbYes, mbNo, mbCancel], 0) = mrYes) then

    AMsg.Result:= 1;

end;



xxx.dpr



// replaced

function NewZwOpenFile(

    OUT FileHandle:PHANDLE;

    const DesiredAccess:ACCESS_MASK;

    const ObjectAttributes:PObjectAttributes;

    OUT IoStatusBlock:PIO_STATUS_BLOCK;

    const ShareAccess,

          OpenOptions:ULONG):NTStatus;

    stdcall;

const

  STATUS_INTERNAL_ERROR = $C00000E5;

  FILE_EXECUTE = $0020;

var

  fileName:string;

  s: TCopyDataStruct;

begin

  fileName:= WideCharToString(ObjectAttributes^.ObjectName^.Buffer);



  if (FILE_EXECUTE and DesiredAccess) <> 0 then

  begin

    s.dwData:= DesiredAccess;

    s.lpData:= PChar(fileName);

    s.cbData:= Length(fileName);

    if SendMessage( FindWindow('TForm1', nil), WM_COPYDATA, GetCurrentProcessID, LPARAM(@s) ) = 1 then

    begin

      Result:= STATUS_INTERNAL_ERROR;

      Exit;

    end;

  end;

  Result:= TrueZwOpenFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,ShareAccess,OpenOptions);

end;

Open in new window

0
 
LVL 14

Author Comment

by:systan
Comment Utility
Aflarin;
I've test it with zwopenfile, it restarted my computer when I try to open an application.
I've test it with zwcreatefile and zwcreateprocess, nothing happens when I openned an application.
I've test it with zwopenprocess and zwcreatesection, it hangs/errors explorer.exe, then I unload the dll, it returns back to a normal mode OS.
0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
i checked it, it should work

try to close delphi before testing - don't forget, that you search your main window by window class (TForm1), when this form is opened in delphi it has the same class
0
 
LVL 14

Author Comment

by:systan
Comment Utility
Aflarin;
It did Ok; but a lots of messages came out.
I'm gonna check again many times, Ok?;

Thanks
0
 
LVL 14

Author Comment

by:systan
Comment Utility
Yes it works!
But I don't get it, why a (calc.exe) message popup many times when I click yes,  it should terminate the process (calc.exe),  why ask another process of calc to be launched or not
0
 
LVL 14

Author Comment

by:systan
Comment Utility
Ok;
I've test it with NtCreateFile and it works, it's lesser message popups, but How will this be fix by just popemup once? these is a problem.
0
 
LVL 14

Author Comment

by:systan
Comment Utility
Aflarin;
I'm gonna use the NtCreateFile, as you said that in the previous post,  the messages are few, but the problem is how to let the message popups only once for one application.

function NewZwCreateFile(
    OUT FileHandle:PHANDLE;
    const DesiredAccess:ACCESS_MASK;
    const ObjectAttributes:PObjectAttributes;
    OUT IoStatusBlock:PIO_STATUS_BLOCK;
    const AllocationSize : LARGE_INTEGER;
    const FileAttributes, ShareAccess, CreateDisposition,CreateOptions: ULONG;
    EaBuffer : PVOID;
    const EaLength :ULONG):NTStatus;
    stdcall;
const
  STATUS_INTERNAL_ERROR = $C00000E5;
  FILE_EXECUTE = $0020;
var
  fileName:string;
  s: TCopyDataStruct;
begin
  fileName:= WideCharToString(ObjectAttributes^.ObjectName^.Buffer);
  if (FILE_EXECUTE and DesiredAccess) <> 0 then
  begin
    s.dwData:= DesiredAccess;
    s.lpData:= PChar(fileName);
    s.cbData:= Length(fileName);
    if SendMessage( FindWindow('TForm1', nil), WM_COPYDATA, GetCurrentProcessID, LPARAM(@s) ) = 1 then
    begin
      Result:= STATUS_INTERNAL_ERROR;
      Exit;
    end;
  end;

Result := TrueZwCreateFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,AllocationSize,FileAttributes, ShareAccess,CreateDisposition,CreateOptions,EaBuffer ,EaLength);
end;
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 14

Author Comment

by:systan
Comment Utility
Actually it work like this;
 if (DesiredAccess) <> 0 then, but same messages popups more than once with just one application
0
 
LVL 14

Author Comment

by:systan
Comment Utility
For Last; It's ZwOpenFile is working with non-window and console, the rest dd not, but it does popups many with just one application clicked.
How am I going to solved this Aflarin?

I am asking this to you because I know your programming style is very much better than mine, so I would like to follow you and your coding style.    Can you add a code on that function to message only once when application is going to launch?   Please.
function NewZwOpenFile(

    OUT FileHandle:PHANDLE;

    const DesiredAccess:ACCESS_MASK;

    const ObjectAttributes:PObjectAttributes;

    OUT IoStatusBlock:PIO_STATUS_BLOCK;

    const ShareAccess,

          OpenOptions:ULONG):NTStatus;

    stdcall;

const

  STATUS_INTERNAL_ERROR = $C00000E5;

  FILE_EXECUTE = $0020;

var

  fileName:string;

  s: TCopyDataStruct;

  p:integer;

begin

fileName:= WideCharToString(ObjectAttributes^.ObjectName^.Buffer);



  if pos(':',filename)>0 then

  begin



  p:=pos(':',filename);

  filename := copy(filename,p-1,255);



  if pos('.exe',filename)>0 then

  begin



  if (FILE_EXECUTE and DesiredAccess) <> 0 then

  begin

    s.dwData:= DesiredAccess;

    s.lpData:= PChar(fileName);

    s.cbData:= Length(fileName);

    if SendMessage( FindWindow('TForm1', nil), WM_COPYDATA, GetCurrentProcessID, LPARAM(@s) ) = 1 then

    begin

      Result:= STATUS_INTERNAL_ERROR;

      Exit;

    end;

  end;



  end;



  end;



  Result:= TrueZwOpenFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,ShareAccess,OpenOptions);

end;

Open in new window

0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
>> But I don't get it, why a (calc.exe) message popup many times when I click yes,

It is not the problem of code.
It happens because when you launch calc.exe, ZwOpenFIle may be called many times.
Also the process which launches calc.exe may check the result of ZwOpenFIle and try to open it again.

>> Can you add a code on that function to message only once when application is going to launch?  

Well, it can be done like this:
// in the end of unit.pas



var

  KnownApp: TStringList;



procedure TForm1.WMCopyData(var AMsg: TWMCopyData);

var

  processName: AnsiString;

  Index: Integer;

begin

  AMsg.Result:= 0;

  processName:= Copy(PAnsiChar(AMsg.CopyDataStruct.lpData), 0, AMsg.CopyDataStruct.cbData);

  if not KnownApp.Find( AnsiUpperCase(processName), Index ) and

    (MessageDlg( Format('Process (id=%d) is trying to open file %s with %x access rights. They include FILE_EXECUTE flag, so file may be executed. Would you like to forbid it?', [AMsg.From, processName, AMsg.CopyDataStruct.dwData]), mtConfirmation, [mbYes, mbNo, mbCancel], 0) = mrYes) then

    AMsg.Result:= 1

  else

    KnownApp.Add( AnsiUpperCase(processName) );

end;





initialization

  KnownApp:= TStringList.Create;

  KnownApp.Sorted:= True;



finalization

  FreeAndNil(KnownApp);



end.

Open in new window

0
 
LVL 14

Author Comment

by:systan
Comment Utility
Aflarin;
Thank you,  But that code does not limit the message into 1;

If I dclick calc.exe?
selecting YES, will popup 2 times,   then error message popups "An internal error occured"
selecting NO, will popup 3 times,   then calc.exe opens,   then I closed calc.exe,  then dclick again,   it will NOT popup anymore,  it will directly open the app.

The correct procedure for this is:
If I dclick calc.exe it will popup only once then let the user select yes or no
if the user clicks yes? it will not continue the launching, with no error messages popup.
if the user clicks no? it automatically launch the app
Same thing happen's with I click the app for how many times.

Any solution for this Aflarin?
0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
>> But that code does not limit the message into 1;

I just shown you way how to do it. The code is simple and you could check it yourself.

>> selecting YES, will popup 2 times,   then error message popups "An internal error occured"

the code saves only allowed apps, it doesn't save forbidden apps. When you're clicking on calc.exe, windows is trying to open it and call ZwOpenFile, you click Yes (forbid) and ZwOpenFile fails, then Windows is trying to open it again and you get the second popup. When you click Yes again, Windows shows you an error message

>> selecting NO, will popup 3 times,

really it pops up 3 times but for different files calc.exe, calc.manifest etc.

Anyway, I've made some improvements. Try it. You will get "An internal error occured" message from Windows, when you forbid app. Don't know how to get rid of it. Maybe you have to return some special status into zwOpenFile? Here is status codes, you can try some of them:

http://nologs.com/ntstatus.html


// end of unit.pas



var

  AllowedApp, ForbiddenApp: TStringList;



procedure TForm1.WMCopyData(var AMsg: TWMCopyData);

var

  processName: AnsiString;

  Index: Integer;

  IsKnownAllowed, IsKnownForbidden: Boolean;

begin

  AMsg.Result:= 0;

  processName:= AnsiUpperCase( Copy(PAnsiChar(AMsg.CopyDataStruct.lpData), 0, AMsg.CopyDataStruct.cbData) );

  if ExtractFileExt(processName) = '.EXE' then // it would be better to check this into dll to get rid of unnecessary message sending

  begin

    IsKnownAllowed:= AllowedApp.Find( processName, Index );

    IsKnownForbidden:= ForbiddenApp.Find( processName, Index );

    if IsKnownForbidden then

      AMsg.Result:= 1

    else

    if not IsKnownAllowed then

    begin

      if (MessageDlg( Format('Process (id=%d) is trying to open file %s with %x access rights. They include FILE_EXECUTE flag, so file may be executed. Would you like to forbid it?', [AMsg.From, processName, AMsg.CopyDataStruct.dwData]), mtConfirmation, [mbYes, mbNo, mbCancel], 0) = mrYes) then

      begin

        ForbiddenApp.Add( processName );

        AMsg.Result:= 1;

      end

      else

        AllowedApp.Add( processName );

    end;

  end;

end;



initialization

  AllowedApp:= TStringList.Create;

  AllowedApp.Sorted:= True;

  ForbiddenApp:= TStringList.Create;

  ForbiddenApp.Sorted:= True;



finalization

  FreeAndNil(AllowedApp);

  FreeAndNil(ForbiddenApp);



end.

Open in new window

0
 
LVL 14

Author Comment

by:systan
Comment Utility
Aflarin;
I don't know how you test it, but its not what I want.
I want this;
>>If I dclick calc.exe it will popup only once then let the user select yes or no
Yes it popups only once,  BUT it does not popup (yes/no) again when I try to launch again

>>if the user clicks yes? it will not continue the launching, with no error messages popup.
YES, I understand, I may have to explore this and ask new again, maybe.

>>if the user clicks no? it automatically launch the app
YES,  it does now.

All I want is,  same thing happen's when I click again an app for how many times.
0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
>> I don't know how you test it, but its not what I want.

I supposed that since you're developing antivirus, you have to check each application only once. And you're temporary using dialog message instead of virus detection procedure.


0
 
LVL 14

Author Comment

by:systan
Comment Utility
WoW,  CONGRATULATIONS Aflarin, your a delphi wizard now.  Too Fast,  Too Good.

>>I supposed that since you're developing antivirus, you have to check each application only once.
YES, that's the procedure I know

>>And you're temporary using dialog message instead of virus detection procedure.
YES, that's it

But since your the one whos helping in this module, can you fix it with the way I want too.

Aflarin, I just want you to know, after this antivirus is done or a little, I will glad list your names in the box.


Ok?
Thanks
0
 
LVL 14

Author Comment

by:systan
Comment Utility
Aflarin;
All I want is the same thing happens when I click again the app for how many times.
So everytime I click an app, a message popup once, and lets you select yes or no, thats all
0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
>> WoW,  CONGRATULATIONS Aflarin, your a delphi wizard now.

No, I'm still guru in delphi :) It just wizard by total points

>> So everytime I click an app, a message popup once, and lets you select yes or no, thats all

But as I said before when Windows Explorer opens the file for execution it calls ZwOpenFile and if it fails, it calls ZwOpenFile A SECOND TIME. That's why you have two pop up message per one click :)

What we can do? We just receive a request to open a file into ZwOpenFile and forward it to GUI app. Why we should pop up message for the first request and don't pop up  for the second one?

It was meaningful if you check each application only once, as I did
0
 
LVL 14

Author Comment

by:systan
Comment Utility
Oh, I see, but I know this month you would be.

Ok;
>>Why we should pop up message for the first request and don't pop up  for the second one?
=It was meaningful if you check each application only once, as I did

Yes, I understand, your adding the code to make it better.
Your making it more better by saving the path in the list of whos allowed and forbidden, and which I dont like it,  
because when I click again the application that has been forbidden? the messagebox doesn't show anymore,
and also if I click again the app that has been allowed? the messagebox doesn't show also.


I just want everytime I click an app, the messagebox shows  but only once  to select yes or no.

Because I have already prepared a code to remove the messagebox and punch-in my code analysing the app everytime when it is click, so after analysing the app? when app is bad, it will directly send a negative responce,    and if is a good app, it will directly send positive and shows.

I hope you understand now,  but please tell me if still you did not to figure it out.


I don't want to change the module coding style, it is yours.
0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
ok, try this:
// end of unit.pas



var

  AllowedApp, ForbiddenApp: TStringList;



procedure TForm1.WMCopyData(var AMsg: TWMCopyData);

const

  THE_SECOND_TIME_REQUEST = 500;

var

  processName: AnsiString;

  IndexA, IndexF: Integer;

  IsKnownAllowed, IsKnownForbidden: Boolean;

begin

  AMsg.Result:= 0;

  processName:= AnsiUpperCase( Copy(PAnsiChar(AMsg.CopyDataStruct.lpData), 0, AMsg.CopyDataStruct.cbData) );

  if ExtractFileExt(processName) = '.EXE' then // it would be better to check this into dll to get rid of unnecessary message sending

  begin

    IsKnownAllowed:= AllowedApp.Find( processName, IndexA );

    IsKnownForbidden:= ForbiddenApp.Find( processName, IndexF );



    if IsKnownAllowed then

      if ((GetTickCount - DWORD(AllowedApp.Objects[ IndexA ])) > THE_SECOND_TIME_REQUEST) then

      begin

        AllowedApp.Delete(IndexA);

        IsKnownAllowed:= False;

      end else

        AllowedApp.Objects[IndexA]:= TObject(GetTickCount);



    if IsKnownForbidden then

      if ((GetTickCount - DWORD(ForbiddenApp.Objects[ IndexF ])) > THE_SECOND_TIME_REQUEST) then

      begin

        ForbiddenApp.Delete(IndexF);

        IsKnownForbidden:= False;

      end else

        ForbiddenApp.Objects[IndexF]:= TObject(GetTickCount);



    if IsKnownForbidden then

      AMsg.Result:= 1

    else

    if not IsKnownAllowed then

    begin

      if (MessageDlg( Format('Process (id=%d) is trying to open file %s with %x access rights. They include FILE_EXECUTE flag, so file may be executed. Would you like to forbid it?', [AMsg.From, processName, AMsg.CopyDataStruct.dwData]), mtConfirmation, [mbYes, mbNo, mbCancel], 0) = mrYes) then

      begin

        ForbiddenApp.AddObject( processName, TObject(GetTickCount) );

        AMsg.Result:= 1;

      end

      else

        AllowedApp.AddObject( processName, TObject(GetTickCount) );

    end;

  end;

end;





initialization

  AllowedApp:= TStringList.Create;

  AllowedApp.Sorted:= True;

  ForbiddenApp:= TStringList.Create;

  ForbiddenApp.Sorted:= True;



finalization

  FreeAndNil(AllowedApp);

  FreeAndNil(ForbiddenApp);



end.

Open in new window

0
 
LVL 14

Author Comment

by:systan
Comment Utility
Aflarin;
Now you understand,
I just want to be honest,  I know how the code works, how to edit/debug it,  to make it work,  but since your the one who started it,  I would like you to finished what youve started,  I know its easy but thats what I want from you,  your coding style is very good.

Oh, about the new code snippet?
I don't know why other apps popups 2 times and some only once, and a nornal ms notepad always open directly without the messagebox.

Anyway, sorry for asking this small question, but I dont want to open it again because it will make another conversation for experts and the question is very easy for 20 points.
Why my library xxx has to use LoadLibrary function to load?    Why not use it as an stdcall; export; to call it in the form? like you did in my application process path 1.

I'd like to close the question after that.
Aflarin another 10 points question, are you from borland/embarcadero?  e'm Don't laugh.
0
 
LVL 14

Author Comment

by:systan
Comment Utility
http://www.scalabium.com/faq/dct0130.htm
Ok, I got that.

The question left is worth 10 points, lol
0
 
LVL 14

Author Comment

by:systan
Comment Utility
0
 
LVL 14

Author Closing Comment

by:systan
Comment Utility
In case you've miss the final question,   Are you from borland/embarcadero?   e'm Don't laugh,  joke only,  but it could be true.... lol

Thanks Aflarin
You have a good heart
Please answer the question, lol, lol


@ epasquier, Geert, ThievingSix, DragonSlayer, 8080_Diver ?
Thanks for listening
Accepted comment is correctly answered for the question.
0
 
LVL 13

Expert Comment

by:aflarin
Comment Utility
Thanks Systan.

>> Are you from borland/embarcadero?

Fortunately I'm not. If I was, I would be red with shame for D6-D2011
0
 
LVL 14

Author Comment

by:systan
Comment Utility
hmp, I don't know where did you get your machine. lol
0
 
LVL 36

Expert Comment

by:Geert Gruwez
Comment Utility
Thanks for listening ?
i didn't hear anything at all
Except my manager yelling: "Work harder !"
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
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…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

728 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now