Solved

Does JournalRecord hook from service require "Allow service to interact With Desktop"?

Posted on 2003-11-11
8
1,255 Views
Last Modified: 2012-05-04
Hello!
  I have restarted working on my work-monitoring utility :-)
  I was wprking with my Journal Record service and noticed that it worked only when I check the "Allow service to interact With Desktop" checkbox. If it is not checked, I get the message "No Journal Hook availible" in my file.
  The service monitors different mouse/keyboard events and logs them in a file "C:\IdlLog.Txt".
  I am running it under Win XP and have compiled it in Delphi 7.
  Can some body tell me why this could happen and what is the solution?
  Here's the unit:
unit WorkUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
  ExtCtrls;

Const
  TimeToSec = 86400;

type
  TService1 = class(TService)
    Timer1: TTimer;
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
    procedure ServiceExecute(Sender: TService);
    procedure Timer1Timer(Sender: TObject);

  private
    { Private declarations }
  public
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;

var
  Service1: TService1;
  MyHook, KHook: THandle;
  LastActivityTime, LastCheckTime, TheTotalIdleCount, TheCurrentIdleCount,
  TheIdleCutOff, TheCurrentWorkCount : TDateTime;
  FHookStarted : Boolean;
  MsgLog: TStringList;
  KbdLog: String;
implementation

{$R *.DFM}

Function SecondOfTheDay(CnvTime: TDateTime): Integer;
Begin
  Result := Round(CnvTime * TimeToSec);
End;

Function GetTimeDiff(CurTime, PreTime: TDateTime): TDateTime;
Begin


  If CurTime < PreTime Then
  Begin
    CurTime := 1 + CurTime;
  End;
  Result := CurTime - PreTime;

End;



Procedure UpdateIdleTime(KeyFlag:Boolean = True);
var
  TimeDiff, CurTime: TDateTime;

Begin

  CurTime := TIME;
  If KeyFlag Then
  Begin
    TimeDiff := GetTimeDiff(CurTime, LastActivityTime);
    If TimeDiff >= TheIdleCutOff Then
    Begin
      TheTotalIdleCount := TheTotalIdleCount + TimeDiff;
      TheCurrentIdleCount := TheCurrentIdleCount + (GetTimeDiff(CurTime, LastCheckTime));
    End
    Else
    Begin
      TheCurrentWorkCount := TheCurrentWorkCount + TimeDiff;
    end;

    LastCheckTime := CurTime;
    LastActivityTime := LastCheckTime;
  End
  Else
  Begin
    TimeDiff := GetTimeDiff(CurTime, LastCheckTime);
    If TimeDiff >= TheIdleCutOff Then
    Begin
      TheCurrentIdleCount := TheCurrentIdleCount + TimeDiff;
    End;
    LastCheckTime := CurTime;
  End;

End;



Function GetWorkStats: Word;

Begin

  Result := SecondOfTheDay(TheCurrentWorkCount);
  TheCurrentWorkCount := 0;

End;


procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  Service1.Controller(CtrlCode);
end;

function TService1.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

function JournalProc(Code, wParam: Integer; var EventStrut: TEventMsg): Integer; stdcall;
var
  s: string;
  KbdFlag: Boolean;
begin
  {this is the JournalRecordProc}
  Result := CallNextHookEx(MyHook, Code, wParam, Longint(@EventStrut));
  {the CallNextHookEX is not really needed for journal hook since it it not
  really in a hook chain, but it's standard for a Hook}
  if Code < 0 then Exit;

  {you should cancel operation if you get HC_SYSMODALON}
  if Code = HC_SYSMODALON then Exit;
  if Code = HC_ACTION then
  begin
    {
    The lParam parameter contains a pointer to a TEventMsg
    structure containing information on
    the message removed from the system message queue.
    }

    s := '';
    KbdFlag := False;
    if EventStrut.message = WM_LBUTTONUP then
      s := 'Left Mouse UP at X pos ' +
        IntToStr(EventStrut.paramL) + ' and Y pos ' + IntToStr(EventStrut.paramH);

    if (EventStrut.message = WM_RBUTTONUP) then
      s := 'Right Mouse Up at X pos ' +
        IntToStr(EventStrut.paramL) + ' and Y pos ' + IntToStr(EventStrut.paramH);

    if (EventStrut.message = WM_MOUSEWHEEL) then
      s := 'Mouse Wheel at X pos ' +
        IntToStr(EventStrut.paramL) + ' and Y pos ' + IntToStr(EventStrut.paramH);

    if (EventStrut.message = WM_KEYUP) then
    Begin
      KbdFlag := True;
      s := 'Keyboard';
      KbdLog := KbdLog + Format('<%d>',[EventStrut.paramL]);

      If wParam = VK_Return Then
      Begin
        KbdFlag := False;
        s := KbdLog;
        KbdLog := '';
      End;
    End;

    if s <> '' then
    Begin
      If not KbdFlag then
        MsgLog.Add(s);
      UpdateIdleTime;
    End;
  end;
end;

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
Var
  CutOffSec, CheckSec: Integer;
begin

  CutOffSec := 5;
  CheckSec := 10;
  MsgLog := TStringList.Create;
  KbdLog :='';
  if FHookStarted then
  begin
    MsgLog.Add('Mouse is already being Journaled, can not restart');
    Exit;
  end;

  LastActivityTime := TIME;
  LastCheckTime := LastActivityTime;
  TheIdleCutOff := CutOffSec / TimeToSec;
  TheTotalIdleCount := 0;
  TheCurrentIdleCount := 0;
  TheCurrentWorkCount := 0;

  MyHook := SetWindowsHookEx(WH_JOURNALRECORD, @JournalProc, hInstance, 0);
  Timer1.Interval := CheckSec * 1000;
  Timer1.Enabled := True;
  {SetWindowsHookEx starts the Hook}
  if MyHook > 0 then
  begin
    FHookStarted := True;
  end
  else
    MsgLog.Add('No Journal Hook availible');
end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
  FHookStarted := False;
  Timer1.Enabled := False;
  Timer1Timer(Timer1);
  UpdateIdleTime;
  UnhookWindowsHookEx(MyHook);
  MyHook := 0;
  MsgLog.Add(KbdLog);
  MsgLog.SaveToFile('C:\IdlLog.Txt');
  MsgLog.Free;
end;

procedure TService1.ServiceExecute(Sender: TService);
begin
 while not Terminated do
    ServiceThread.ProcessRequests(True);
end;

procedure TService1.Timer1Timer(Sender: TObject);
Var
  TotalIdl, CurIdl, CurWrk: Word;
begin
  CurWrk := GetWorkStats;
  MsgLog.Add(Format('Work = %d',[CurWrk]));
end;

end.

0
Comment
Question by:snehanshu
8 Comments
 
LVL 11

Assisted Solution

by:robert_marquardt
robert_marquardt earned 20 total points
ID: 9777128
Applying my common sense:
You want to access an application. An application runs on a desktop.
0
 
LVL 5

Author Comment

by:snehanshu
ID: 9777165
>>You want to access an application.
I thought I wanted to catch windows messages.
Does it mean that keyboard hooks also would not work if I haven't checked this thing? I haven't tried it, but want to know.
What classifies as "Desktop thing" and what does not?
...Snehanshu
0
 
LVL 6

Assisted Solution

by:pritaeas
pritaeas earned 50 total points
ID: 9778026
You may find some info here

http://www.geocities.com/macrotech_tr/API.html

hth, pritaeas
0
 
LVL 6

Assisted Solution

by:GloomyFriar
GloomyFriar earned 50 total points
ID: 9778365
When you have the "Allow service to interact With Desktop" checkbox unchecked your service run in a "black box" so it can't do what you want.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 5

Author Comment

by:snehanshu
ID: 9778459
GloomyFriar,
>>your service run in a "black box"
  Is it true about JournalRecord or any hook?
  And is there some place where I can find information on what lies inside the black box and what lies outside?
:-)
Thanks,
...Snehanshu
0
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 130 total points
ID: 9778955
imo mouse and kbd aren't accessible from a service
you can have different settings for them for each user
that's why you need to interact with the desktop

I also have a monitoring service and it needs to be interactive (I use the mouse and kbd hooks separately)

a simple rule of thumb .. anything that can be customized on a user level can't be accessed from a service unless it's interactive OR by using user Impersonation
0
 
LVL 5

Author Comment

by:snehanshu
ID: 9786853
Lee_Nover,
>>unless it's interactive
  I didn't know you could enable that check box on install just by changing the interactive property to true at design time!
  I have also got a few links from experts at Windows Programming TA and looks like I am all set to continue my task for now.
http://www.experts-exchange.com/Programming/Programming_Platforms/Win_Prog/Q_20802669.html
  Thank you all your help.
...Snehanshu
0
 
LVL 5

Author Comment

by:snehanshu
ID: 9786855
>>Thank you all your help.
Thank you all for your help.
:-)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

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…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

914 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

15 Experts available now in Live!

Get 1:1 Help Now