Passworded screensaver

Blitz3D Forums/Blitz3D Programming/Passworded screensaver

Graythe(Posted 2005) [#1]
When boxes loaded with XP and Win2K resume from a passworded screensaver Blitz breaks with "Memory acces violation". I believe the error actually occurs when the screensaver is invoked. Oddly, it doesn't happen when the screensaver is not password protected.

Is there a way around that? (other than remove password protection?)


Graythe(Posted 2005) [#2]
bump


jfk EO-11110(Posted 2005) [#3]
I'd also like to know a solution for this, esp. since I aint got Win2000 or XP here, but I used to release Screensavers :/
Graythe - did you try to isolate the problem? With a very simlpe failsave program? Are you sure it isn't caused by your program only because it's paused by the prompt that will mess up the timing?

Maybe you should try something like

While keydown(1)=0
delay 10
wend
end

So you know it's not your fault when it happens again.


Graythe(Posted 2005) [#4]
Hi JFK,

I wrote a VB6 dll that checks the name of the active window. If it returns an empty string then I do not call renderworld. When the name of the active window reverts to a readable sequence then I do a clearworld and re-select the graphics mode and recreate objects.

Probably I'm using a nuke to crack a walnut but it seems to work!

It will also solve some problems that I had with the calculation of durations in BB. My thanks to Kurtz and Kanati for information which allowed me to create the dll (www.vbadvance.com).

http://blitzbasic.com/Community/posts.php?topic=28210


Graythe(Posted 2005) [#5]
Screensavers eh? What with all the wizz wazz like password and configurable options an' all?!


Picklesworth(Posted 2005) [#6]
I wrote a VB6 dll that checks the name of the active window. If it returns an empty string then I do not call renderworld. When the name of the active window reverts to a readable sequence then I do a clearworld and re-select the graphics mode and recreate objects.

I'm almost sure you can do this in Blitz with User32.decls.


Graythe(Posted 2005) [#7]
Doh!


jfk EO-11110(Posted 2005) [#8]
Everything other than /S in the commandline will end the app immediately. So there's no Configuration or Preview (/C + /P). The password dialog is done by Windows, isn't it?

The hard part is to make sure the App will find its content. I came away from renaming the exe to scr and copying it to the system folder. Instead I use the Clickteam Installer that allows to install something as the active Screensaver, it will also open the Screensaver settings after the installation.

One problem with a SCR that is copied to the system folder is: Due to some internal windows stuff the SCR app won't know where it was started, so even when its media files are in the system folder too (wich is real messy) it won't find it unless you do a "ChangeDir SystemProperty$("systemdir")" first. Now when you use the Clickteam installer, it will create a Folder in th Programs Folder of the OS, so you can keep the mediafiles there, a much more proper solution. Nevertheless you still need to do a ChangeDir SystemProperty$("appdir") first to allow your screensaver to find it's media files. And the EXE still need to be renamed to .SCR.


Yan(Posted 2005) [#9]
The password dialogue is done by Windows, isn't it?
On 2K, XP and NT (I think), then yes, but it's the responsibility of the screen saver on 9x.


@Graythe - Try running this and let your saver start (wont work for a preview)...
; user32.decl
;------------------
; .lib "user32.dll"
; SystemParametersInfo(uAction%, uParam%, lpvParam*, fuWinIni%) : "SystemParametersInfoA"
; MessageBeep(wType%)
;------------------

; Should work on 9x, 2K and XP

Const SPI_GETSCREENSAVERRUNNING = $72

Local time = MilliSecs()
Local bnk = CreateBank(1)

Repeat
    If (MilliSecs() - time) >= 1000
        If SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, bnk, 0)
            If PeekByte(bnk, 0) Then MessageBeep(-1)
        EndIf
        time = MilliSecs()
    EndIf
    
    Delay 10
Until KeyHit(1)

End
Here's a more fully featured version I have. Written for BMax, but should be easy enough to convert...
'Conversion of some C source I found on the net.
' Should work on 9x, 2K, XP and NT

Extern "win32"
    Function GetLastError()
    Function SystemParametersInfo(uiAction, uiParam, pvParam Var, fWinIni) = "SystemParametersInfoA@16"
    Function OpenDesktop(lpszDesktop$z, dwFlags, fInherit, dwDesiredAccess) = "OpenDesktopA@16"
    Function CloseDesktop(hDesktop)
End Extern

Const ERROR_ACCESS_DENIED = $5
Const SPI_GETSCREENSAVERRUNNING = $72
Const MAXIMUM_ALLOWED = $2000000

Function SaverIsRunning()
    Local running = False
        
    If SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, running, 0)
        If running Then Return True
    EndIf
        
    Local hDesk = OpenDesktop("screen-saver", 0, False, MAXIMUM_ALLOWED)
    If hDesk
        CloseDesktop(hDesk)
        Return True
    EndIf
    
    If GetLastError() = ERROR_ACCESS_DENIED Then Return True
End Function



Graythe(Posted 2005) [#10]
Hi Yan,

I appreciate the effort, and I can see that your own construction is somewhat finer than my own - but the screensaver isn't the problem - it's the password routine. Only if the user's screensaver is passworded does my BB app fall over. No matter, my cludge is working.


Graythe(Posted 2005) [#11]
Well, actually my cludge doesn't work, not all the time. I'll try the user32 route, thanks for illuminating the path.


Graythe(Posted 2005) [#12]
Well, your User32.decls seems to work just dandy:- It tells me if the screensaver is running and also seems pin the error to renderworld after a passworded screensaver has been invoked.

Using Yan's method I can determine if the screensaver is running and do a clearworld (and also introduce a .1 second delay so as to allow other tasks more cpu cycles - before I did that the screensaver ran like it was powered by steam). When the screensaver is no longer running I delay for 2 seconds (1 second seems to work - much less that that and the dreaded "Unable to create 3D scene" message appears) and re-initialise the screen.

I'm purely guessing that the windows password routine somehow makes BB's hooks to the front/backbuffers invalid. However, other games/apps don't seem to suffer?!

Thanks, once again, for the routemap!


Graythe(Posted 2005) [#13]
Nope - I tell a lie - the app just fell over and it didn't seem to be doing a renderworld at the time. Hmmm.


Graythe(Posted 2005) [#14]
O.k. I've actually made some progress.

There seems to be a small period of time when the PC can be between applications. There is also the password window which can be running when the screensaver is not.

By implementing extra checks to cover those events it seems to hang together.


jfk EO-11110(Posted 2005) [#15]
What happens if I end the screensaver as soon as the mouse is moved ar a key was pressed? Shouldn't this end it before the crash happens? And wouldn't windows restart the screensaver if the password was not valid?
Unfortunately I cannot test it because I ain't got XP here.


Yan(Posted 2005) [#16]
Hehe...Sounds like you're having fun there Graythe. ;o)

I'd somehow got it into my head that that API call would return true for the password window too. Sorry about that, but it seems like you're getting there, at least. :o)

If all else fails, you do have the option of disabling the screen saver whilst your app is running...
Const SPI_SETSCREENSAVEACTIVE = $11
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, False, Null, 0) ;'Disables
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, True, Null, 0) ;'Enables
It's a bit heavy handed but better than a crash.


Graythe(Posted 2005) [#17]
Thats a great idea!

@JFK - Yep -If the screensaver starts and I immediately move the mouse or jab a key then the screensaver collapses without issue. I've never tried inputting the wrong password (so far) - so I dunno - yet.

Possibly - just very occaisionally, I think... the call to determine if the screensaver is running doesn't return me the correct result. More likely (of course) is that my code isn't flexible enough. Just possibly, windows starts the screensaver halfway thru a screen update so I may need to check before each graphical operation? Oh hum. Dunno how feasible that is.

I may have to resort to being heavy handed. It's great to know that it is an option!