Security Attributes in CreateFileMapping

Hi!
 This is my first post to the exchange.
 I managed to create a DLL that hooks to keyboard and mouse events.
 It runs fine with normal applications, but when I try to use it from a windows service (TService), I get an access violation error.

The code that does not work is:

     hObjHandle := CreateFileMapping ($FFFFFFFF, nil, PAGE_READWRITE, 0,
       dwAllocSize, 'HookRecMemBlock');

GetLastError returns 5 (Access denied)
I searched the web and it seems that there is a windows security related issue.  I think the problem lies in the second parameter, but do not know what should I replace the nil with.

It seems for now that I found a workaround: by using journalrecord (WH_JOURNALRECORD) within the service instead of using a DLL,
(Ref: http://www.swissdelphicenter.ch/torry/showcode.php?id=1729),
but still, would like to know about the security attributes in delphi.

Can some body help please?

Thank you,
...Snehanshu
LVL 5
snehanshuAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DaFoxCommented:
Hi!

This is an example I once found on the net.


// create memory map file
procedure OpenMemoryMap(dwAllocSize:DWORD);
const
  SECURITY_DESCRIPTOR_REVISION = 1;
var
  SecurityDescriptor:TSecurityDescriptor;
  SecurityAttr:TSecurityAttributes;
  RetVal:Integer;
begin
  try
    lpHookRec:=NIL;
    if Version=WinNT then
    begin
      SecurityAttr.nLength:=SizeOf(SECURITY_ATTRIBUTES);
      SecurityAttr.bInheritHandle:=TRUE;
      SecurityAttr.lpSecurityDescriptor:=@SecurityDescriptor;
      if not InitializeSecurityDescriptor(@SecurityDescriptor,SECURITY_DESCRIPTOR_REVISION) then
      begin
          RetVal:=GetLastError;
          raise Exception.CreateFmt('Unable to initialize security descriptor. Windows error=%d', [RetVal]);
      end;
      if not SetSecurityDescriptorDacl(@SecurityDescriptor,TRUE,NIL,FALSE) then
      begin
          RetVal:=GetLastError;
          raise Exception.CreateFmt('Unable to set security descriptor dacl. Windows error=%d', [RetVal]);
      end;
      if not SetKernelObjectSecurity(GetCurrentProcess,DACL_SECURITY_INFORMATION,@SecurityDescriptor) then
      begin
          RetVal:=GetLastError;
          raise Exception.CreateFmt( 'Unable to set kernel object security. Windows error=%d', [RetVal]);
      end;
      hObjHandle:=CreateFileMapping($FFFFFFFF, @SecurityAttr, PAGE_READWRITE, 0, dwAllocSize, 'HookRecMemBlock');
    end
  else
    hObjHandle:=CreateFileMapping($FFFFFFFF, NIL, PAGE_READWRITE, 0, dwAllocSize, 'HookRecMemBlock');

    if hObjHandle=0 then exit;
    // get a pointer to our process wide memory mapped variable
    lpHookRec:=MapViewOfFile(hObjHandle, FILE_MAP_WRITE, 0, 0, dwAllocSize);
    if lpHookRec=NIL then
      begin
        CloseHandle(hObjHandle);
        exit;
      end
    else
      begin
        // initialize memory map variables
        with lpHookRec^ do
          begin
  // your variables here
          end;
      end;
  except
    on e:exception do;
  end;
end;

// close memory map file
procedure CloseMemoryMap;

begin
  try
    // delete our process wide memory mapped variable
    if lpHookRec<>NIL then
      begin
        UnMapViewOfFile(lpHookRec);
        lpHookRec:=NIL;
      end;
    if hObjHandle>0 then
      begin
        CloseHandle(hObjHandle);
        hObjHandle:=0;
    end;
  except
    on e:exception do;
  end;
end;


Regards,
Markus

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
snehanshuAuthor Commented:
Thank you Mark!
That did solve my problem. What a relief!
But the version check did not work (Version = WinNT), the compiler says WinNT is an undeclared identifier. Any fix for that? (I am compiling with Delphi 5).
The answer very much solved my problem, so I shall mark the answer as accepted, but it would be nice if you could let me know the solution for the version check.
Also, I have a query on whether I should use a hook or a journalrecord. It would be nice if you could have a look at that to.
(Ref: http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20750833.html)

Thanks again,
...Snehanshu
DaFoxCommented:
Hi Snehanshu,

sorry, my fault. You just have to check for the platform (NT platform does need the SecurityDescriptor, 9x doesn't).
Just use this function instead of Version = WinNT:

function IsNT: Boolean;
var
  OS: TOSVERSIONINFO;
begin
  OS.dwOSVersionInfoSize := SizeOf(TOSVERSIONINFO);
  GetVersionEx(OS);
  Result := (OS.dwPlatformId = VER_PLATFORM_WIN32_NT);
end;

-

// ...
  lpHookRec:=NIL;
  if (isNT) then
  begin
    SecurityAttr.nLength:=SizeOf(SECURITY_ATTRIBUTES);
// ...

Markus

PS: I will take a look at your other question. Dunno if I have an answer for you though.
snehanshuAuthor Commented:
Thank you Markus!
Now, my DLL is all-platform compatible!
:)

...Snehanshu
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.