4

I'm asking this question because it turns out that there's some difficulty in writing a screensaver app in Delphi that's capable of running from the Logon screen.

See question: Windows 7 logon screensaver in Delphi

I've narrowed down the problem (or at least one problem) to a particular Win API call CreateEvent.

SyncEvent := CreateEvent(nil, True, False, '');
if SyncEvent = 0 then
  RaiseLastOSError;

This code only fails if called from the Logon screen. And GetLastError returns that access is denied. So clearly the security restrictions on the Logon screen prevent CreateEvent(nil, True, False, ''); from creating the event as desired.

(I don't really see how an Event could be an exploitable security risk.)

So, the question is: Is it possible to create an Event from the Logon screen? Presumably via either:

  • Using an appropriate lpEventAttributes
  • Or calling CreatingEventEx instead.

Although the problem was experienced in Delphi, this is more about the Win API. So feel free to answer in your language of choice.

Community
  • 1
  • 1
Disillusioned
  • 14,635
  • 3
  • 43
  • 77
  • Craig, I'm absolutely no expert at this and maybe I dreamt it, but I'm sure there was a question about this in the Borland groups back in the Win2k or even NT era and the answer at the time was that you had to supply a replacement for Gina.Dll if you wanted to do anything inside the Windows station of the logon screen. Acc to this q, it's different post XP but I imagine you knew that: http://stackoverflow.com/questions/1917790/a-gina-replacement-in-a-net-language – MartynA Jul 13 '14 at 19:50
  • @MartynA I must confess much of this is new to me. I just did some investigation because the question about Logon screensavers piqued my interest. However, I have my doubts about GINA being relevant because [this question](http://stackoverflow.com/q/9506690/224704) suggests that GINA has been replaced as of Windows Vista. Also, I don't know what the asker of the Logon screensaver question actually intended doing. Perhaps he wanted to write a simple slideshow screensaver. It turns out that of the standard Win-7 screensavers, only the blank screen works due to Direct3D restrictions. – Disillusioned Jul 13 '14 at 20:06
  • 4
    Try setting the last parameter of `CreateEvent()` to `nil` instead of `''`. There is a difference between a nil pointer and a pointer to a zero-length string. The [documentation](http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396.aspx) does not say anything about a zero-length string being treated any differently than any other named string. If you want an unnamed event, use `nil`. – Remy Lebeau Jul 13 '14 at 20:35
  • 2
    @RemyLebeau Excellent catch! Please go ahead and post as an answer. – Disillusioned Jul 13 '14 at 21:00
  • 2
    @Anonymous downvoter: Mind sharing what's wrong with the question so I can do better next time? – Disillusioned Jul 14 '14 at 07:37

1 Answers1

7

Try setting the last parameter of CreateEvent() to nil instead of '' . There is a difference between a nil pointer and a pointer to a zero-length string. The documentation does not say anything about a zero- length string being treated any differently than any other named string. So maybe there is another zero-length-named event that exists somewhere else on your machine that your app does not have access to, thus the Access Denied error when CreateEvent() tries to access the existing event and fails. If you want to create an unnamed event, use nil instead.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks for that. Now that I'm more consciously aware that `PChar` is a little richer than `string` in its ability to differentiate `nil` and `''`, it's led me to discover more little mistakes in Delphi. E.g. `TSimpleEvent` in SyncObjs wraps `CreateEvent` with the constructor taking a string for the name. So it's impossible to create an unnamed event. Even worse it doesn't check the result of the API call, so if you use `TSimpleEvent` from a Logon screensaver, you'll quietly get a useless `TSimpleEvent` instance. – Disillusioned Jul 14 '14 at 19:54
  • 1
    The `T(Simple)Event` bug has already been reported to QC, and still exists in XE6: [#100175 SyncObjs.TEvent invalid construction](http://qc.embarcadero.com/wc/qcmain.aspx?d=100175) – Remy Lebeau Jul 14 '14 at 20:34