Services für Win9x

Während der Windows 98 und ME Support im Jahr 2003 ablief, hatte ich noch 2008 den Auftrag, Software so zu schreiben, dass sie unter Windows 9x ausführbar ist.

Dabei ging es “nur” um normale UIs.

Dienste wie unter NT gab es nicht … oder vielleicht doch …?


Es ist schon ein bisschen ironisch, dass sich die damals junge Linux Community zu Recht über “das schlechte Windows” aufregte, und dabei fast ausschließlich Probleme mit Windows 95 und 98 nannte.
NT4 und 2000 konnte man dann nur als zu aufgebläht bezeichnen.

Die strukturierte Verwaltung von “Diensten” (Daemons unter Linux) hatte aber nur NT wirklich drauf, während sich das junge Linux mit init-Scripten plagte und interessanterweise nicht viel mehr hinbekam, als eben Windows 9x.

Kein Service Manager

Der Service Control Manager (SCM) definiert unter NT die Infrastruktur eines Dienstes. Eine EXE startet und registriert sich selbst per API als Dienst inklusive Callbacks für diverse Statusänderungen und die Service-Runtime führt diese Callbacks als RPCs dann “kontrolliert” aus.

Win9X kannte einen solchen Dienst nicht, hatte aber einen für damals typischen billigen Trick, um so etwas Ähnliches wie Hintergrunddienste anzustarten.

Registry + Registration = Service

Viele Leute kennen den Registry-Key
HKEY_LOCAL_MACHINE\Software\Microsoft\CurrentVersion\Run, dessen Einträge beim Login durchgelaufen werden und die String-Values einfach als Prozesse gestartet werden.

Für Dienste gab es HKEY_LOCAL_MACHINE\Software\Microsoft\CurrentVersion\RunServices, dessen Einträge schon beim Start des Windows-UI abgearbeitet wurden. So konnte man per Key-Namen jedem Dienst einen Namen zuordnen und der String-Wert war einfach die Kommandozeile, die den Dienst starten sollte.

Da bei der Abmeldung eines Benutzers auch alle laufenden Prozesse gekillt wurden, musste man noch einen Möglichkeit schaffen, die Dienst-Prozesse als ebensolche zu markieren. Und das geschah mit folgender kernel32 API:

1DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType);

Diese Funktion existierte nur in Windows 9x und nicht NT, doch man konnte sie per GetProcAddress() laden um zu beiden OS-Typen kompatibel zu bleiben.
Ein Aufruf von RegisterServiceProcess(GetCurrentProcessId(), 1) registrierte einen Prozess als Dienst, und schon wurde er nicht mehr beim Logout beendet.

Anwendung

Manche Netzwerkserver für Windows wie FTP, HTTP oder NTP nutzten diese Methode um im Hintergrund ihre Dienste durchzuführen.
Doch da Windows 9x selten für solche “Dienste” genutzt wurde, ging diese Methode wieder in Vergessenheit.
Man findet sie noch in sehr alten Code-Repositories in Softwareständen vor 2003, doch danach wurde der Win9x-Service Support systematisch überall entfernt.

Die Funktion RegisterServiceProcess selbst findet man “leider” in zahlreichen alten Foren als “Hacker-Funktion” um das eigene Programm vor dem Task-Manager zu verstecken.
Wer also Böses vor hatte und nicht wollte, dass das eigene Programm leicht gekillt werden konnte, registrierte es fälschlich als Dienst.

Fazit

Auch diese Technik wandert nun ins GATE Projekt und tut dort seinen Dienst, wenn die NT-APIs nicht geladen werden können … sprich, wenn ein Prozess unter Windows 9x gestartet wird.

Da diese Funktion aber nur in ANSI-Kompilaten Sinn macht, ist dieser Teil in Unicode- oder x64- Varianten generell per #ifdef deaktiviert.

📧 📋 🐘 | 🔔
 

Meine Dokus über:
 
Weitere externe Links zu:
Alle extern verlinkten Webseiten stehen nicht in Zusammenhang mit opengate.at.
Für deren Inhalt wird keine Haftung übernommen.



Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!