$100 reward for solving SDL/WindowsNT problems before log on

Hi guyz!

I will send a 50$ reward to the first one who sends a solution for one of these two problems
to this list:
Both are related to using SDL (1.2.2) as part of a screensaver before log on
under Windows NT.

Problem 1 (50$ reward,easy?):=============================
If I run an SDL program before log on (when there’s just the box saying "Press
Ctrl+Alt+Del to log on) , I cannot run it anymore after log on
without getting the following error message:

“Initialization of the dynamic link library C:\WINNT\system32\DDRAW.dll failed.
The process is terminating abnormally”.

To reproduce it, compile the simple logon.c program pasted at the end of
this message, replace the file c:\WINNT\system32\logon.scr with the executable
and log out. After ~15 minutes, Windows will run the screensaver logon.scr,
and thus our little SDL program, which in turn creates the file "message.txt"
in c:
If you now log on, verify that message.txt is present and run logon.scr manually -
you will get the above error message.

Obviously using the same DLL before and after log on doesn’t work.

I tried the following things already:

  • Searching the Microsoft Knowledge Base with the error message. It suggests
    to change a key in the registry, which has no effect at all.
  • Compiling the SDL library without DirectDraw support. This removes the
    symptoms, but not the problem. The error message disappears, but I still
    get the same message for other DLLs which are used by the SDL application.

P.S.: I cross-compiled everything under Linux, using the standard SDL-cross-
compilation tools.

Problem 2: (50$,harder)

If I run an SDL fullscreen program before log on, it sometimes disappears
from the screen but continues running in the background. When this has
happened, it is not possible any more to set an SDL_FULLSCREEN videomode.
This problem is non-reproducable and occurs on average once in five days.
I traced it down into the SDL library and will give you a detailed
description. My hope is that someone familiar with NT internals has
an idea of what might be going on:

  1. I create a simple non-SDL program and save it as logon.scr in
    C:\WINNT\system32\ This program is run by Windows NT
    as a screensaver, and just checks if the main SDL application
    is already running. If yes, it exits, otherwise it runs the
    SDL application. Windows NT is known to occasionally run
    a screensaver more than once, and this procedure makes sure
    that no second SDL application is started while another one
    is running.

  2. Within the main SDL application I set the videomode with

vga_surface=SDL_SetVideoMode(1024,768,16,SDL_FULLSCREEN|SDL_HWSURFACE);

Everything runs perfectly.
Then I wait for maximally 5 days (sometimes just hours),
and suddenly my SDL application is not
visible any more, instead the screen shows the standard
"Press Ctrl+Alt+Del" logon message. The SDL program is however
still running in the background, it just lost the connection
to the display.

As soon as this has happened, all further calls SDL_SetVideoMode
cannot bring the application up again. SDL_SetVideoMode does not
fail, but the SDL_FULLSCREEN flag is not set in the SDL_Surface
structure. I traced these SDL_SetVideoMode calls down to
/src/video/windib/SDL_dibvideo.c and found that the Windows API
call "ChangeDisplaySettings(&settings, CDS_FULLSCREEN)"
now fails and returns -1 instead of DISP_CHANGE_SUCCESSFUL.

Does anyone have an idea what might be the reason for this
complete failure of ChangeDisplaySettings?

I already tried to pass additional parameters:
ChangeDisplaySettings(&settings,CDS_FULLSCREEN|CDS_RESET|CDS_SET_PRIMARY);
but without result.

Thanks for your help,
Elmar

logon.c

#include “SDL.h” /* All SDL App’s need this */
#include <stdio.h>

int main(int argc,char **argv) {
FILE *fp;

fp=fopen("c:\\message.txt","w");
fprintf(fp,"Initializing SDL.\n");

/* Initialize defaults, Video and Audio */
if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)==-1)) {
    printf("Could not initialize SDL: %s.\n", SDL_GetError());
    exit(-1);
}

fprintf(fp,"SDL initialized.\n");

fprintf(fp,"Quitting SDL.\n");

/* Shutdown all subsystems */
SDL_Quit();

fprintf(fp,"Exit....\n");
fclose(fp);

exit(0);

Possible cause for your problem (this is just a hunch, zero experience in
system-level NT programming ^_^) is that maybe NT closes screen saver
applications not-so-gracefully, therefore not letting your application
reach SDL_Quit(). I have no way to test that approach now, sorry. Using
atexit(SDL_Quit) is worth trying.

Petri Latvala

Possible cause for your problem (this is just a hunch, zero
experience in system-level NT programming ^_^) is that maybe NT
closes screen saver applications not-so-gracefully, therefore not
letting your application reach SDL_Quit(). I have no way to test
that approach now, sorry. Using atexit(SDL_Quit) is worth trying.

This can in fact solve both problems, since in the first case the
screensaver is probably beeing killed coldheartedly when the user
press ctrl+alt+del, and in the second case some stupid background
process kills the screensaver (happened to me in win2k a few times).–
Trick


Linux User #229006 * http://counter.li.org

Problem 1

If I run an SDL program before log on (when there’s just the box saying "Press
Ctrl+Alt+Del to log on) , I cannot run it anymore after log on
without getting the following error message:

“Initialization of the dynamic link library C:\WINNT\system32\DDRAW.dll failed.
The process is terminating abnormally”.

perhaps just run the screensaver with "SDL_VIDEODRIVER=windib"
then you won’t be using any directdraw libraries, which may
allow the screensaver to exit without causing problems.

are you sure you’re running NT, not 2000? anyways, it should
be easy enough to use putenv or something when initializing
the screensaver.

This can in fact solve both problems, since in the first case the
screensaver is probably beeing killed coldheartedly when the user
press ctrl+alt+del, and in the second case some stupid background
process kills the screensaver (happened to me in win2k a few times).

atexit() wouldn’t do a thing for you in this case.

Did someone say this happens with the windib driver, too?

–ryan.

Thanks for the first bunch of answers to the “$100 question”.

Petri Latvala and Trick suggested to add “atexit(SDL_Quit)” to my program.
The modified version is attached below, and unfortunately nothing changed.
If you look at the source code, this result is clear:
This program really just inits SDL and exits immediately, without waiting
for any user input, without giving WindowsNT the chance to terminate
it “ungracefully”. So it really doesn’t matter if I use atexit() or
call SDL_Quit directly. Running this program before log on is enough to "pollute"
the DLLs for use after log on.

Pete Shinners suggested to define an SDL_VIDEODRIVER=windib environment variable
in order to keep SDL from using DirectDraw. This is equivalent to compiling
SDL without DirectDraw support which I described in my initial message.
(Which only solved the DDRAW.dll problem, but not problems with other DLLs which
I MUST use and cannot simply disable).
Anyway, I added the SDL_VIDEODRIVER environment variable as Administrator in
the Control Panel->System window to both the “System” and “User environment”,
logged out, waited for the test program below to be run, logged on again,
ran the program again and got the same error message “DLL initialization failed”.
So unfortunately this also didn’t work.

So the 100 bucks are still waiting… :wink:
However, I just searched through usenet group microsoft.public.windowsnt and found
that quite a lot of people have this sort of problem with screen savers,
and it appears to be a Windows NT bug, which can with a lot of luck be solved
by installing Service Pack 5 “up to three times in a row” :wink:
And it seems to be gone with Windows 2000, so problem 1 is maybe not solvable
at all…

#include “SDL.h” /* All SDL App’s need this */
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char **argv) {
FILE *fp;

atexit(SDL_Quit);

fp=fopen("c:\\message.txt","w");
fprintf(fp,"Initializing SDL.\n");

/* Initialize defaults, Video and Audio */
if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)==-1)) {
    printf("Could not initialize SDL: %s.\n", SDL_GetError());
    exit(-1);
}

fprintf(fp,"SDL initialized.\n");

fprintf(fp,"Quitting SDL.\n");

fprintf(fp,"Exit....\n");
fclose(fp);

//SDL_Quit();

exit(0);

}