...someplace, where there isn't any trouble? Do you suppose there is such a place, Toto?

Ein echter Hinkucker!

Hey, das ist cool!

Nach kürzester Zeit sieht man einen wandernden grünen Punkt, obwohl gar keiner da ist und wenn man auf unendlich fokussiert verschwinden die rosa Punkte komplett.

Muß ein API doppeltes Schließen eines HANDLEs oder Verwendung eines ungültigen HANDLEs aushalten?

Das war gestern die Frage in Mission Control und SFRs Standpunkt war: "Ja. auf jeden Fall!". Mein Standpunkt war: "Well, it depends." SFR schreibt nämlich gerade superfiesen Unittesting-Code und ist dabei einigen Läßlichkeiten in einem API von DEI auf die Spur gekommen. SFR hat nämlich ein HANDLE des APIs zweimal geschlossen und hat damit gerechnet, daß die Funktion zum Schließen beim zweiten Mal einen ordentlichen Fehlerrückgabecode liefert. Tatsächlich ist jedoch der Prozeß gecrasht. Jedenfalls war's so ähnlich. Bei den nachfolgenden Überlegungen gehe ich immer davon aus, daß das API in Form einer DLL implementiert ist und nicht als individuelle Source Files.

Wenn man solch einen Fehler *immer* graceful abhandeln will, muß man zu einigen Maßnahmen greifen, die vielleicht nicht unbedingt immer so schön sind. Was man braucht, ist dann immer ein Set (wenn man in STL denkt), das die aktuell für den Prozeß gültigen HANDLEs beinhaltet und jedes API, das ein HANDLE entgegennimmt, muß das HANDLE am Anfang prüfen und garantieren, daß im weiteren Verlauf der Codeausführung im API das HANDLE auch immer gültig bleibt, denn es könnte ja sein, daß unmittelbar nach der Gültigkeitsprüfung der aktuelle Thread preempted wird und ein nebenläufiger Thread das HANDLE schließt. Wenn dann der Thread im API wieder eine Zeitscheibe bekommt und weiter mit dem HANDLE operiert, kann es ja dann genauso scheppern. Die andere Variante wäre, daß man sich innerhalb der Prüfung, die natürlich von einer critsec geschützt sein muß, die threads gegenseitig ausschließt, alle relevanten Daten für den weiteren Verlauf des API-Codes kopiert und dann nur noch mit Kopien arbeitet.
All das erfordert aufwendige Synchronisationsmechanismen und nach meinem unmaßgeblichen Dafürhalten auch eine per-Prozeß-Initialisierungsroutine, die das prozeßweite HANDLE-Set und seine Synchronisationsobjekte aufsetzt, gepaart natürlich mit einer prozeßweiten Deinitialisierungsroutine. Denn wir benutzen ja keine globalen Objekte für sowas, die wir von der runtime Erzeugen lassen, oder? Doch? Und einen weiteren Effekt hat man dadurch: Alle APIs müssen zumindest eine zeitlang durch das prozeßweite HANDLE-Set durchtunneln, wodurch sich ein "Lock Convoy" ("Boxcar Problem") ergeben kann. Die Performance wird also zumindest nicht gesteigert durch sowas.

Es gibt aber auch einen psychologischen Aspekt des Problems: Eigentlich ist doppeltes Schließen eines HANDLEs oder ein Operieren mit ungültigen HANDLEs ein Programmierfehler, daran gibt es nichts zu deuteln. Ein Bruder-Leichtfuß-Programmierer, der ein API benutzt, tendiert schon auch mal dazu, Fehlercodes von APIs zu ignorieren und einfach nicht auszuwerten. Er wird also eventuell nie im Leben das doppelte Schließen des HANDLEs bemerken und vielleicht noch andere "silly things" (O-Ton SBRYANT) tun wenn er ungültige HANDLEs verwendet. Crasht hingegen sein Programm an dieser Stelle, kann er nicht umhin, sich mit dem Programmierfehler zu befassen. Ein super-graceful API kann also durchaus Fehler des API-Anwenders vertuschen.

Eine Variante des Themas wäre, daß das API nur die Verwendung von HANDLEs gestattet, die auch in dem Thread erzeugt wurden, wo sie verwendet werden, d.h. ich darf ein HANDLE nicht in einen anderen Thread weiterreichen. Damit hätte man unter dem Preis dieser Limitation das Boxcar-Problem beseitigt. Das setzt dann aber ein per-thread-HANDLE-Set, einen per-Thread-Initialisierer/Deinitialisierer und einen TLS-Slot mehr pro-Prozess voraus und TLS-Slots sind knappe prozeßweite Ressourcen. There ain't no such thing as a free meal.

Drum bin ich der Meinung, daß man die Frage im Subject dieses Blogposts für jedes API im Einzelfall prüfen und festlegen muß, es aber eine pauschale Antwort nicht geben kann.

(Edited: Fixed Typos)

A helluva lot of Quickies!

Heute war ein ereignisreicher Tag. In und um Mission Control gab es die interessantesten Dinge zu bestaunen. Beispielweise im Hautatmer-Office nebenan Incis Kugelschreiber. Der schaut nämlich so aus:

Natürlich behauptet Inci, das sei der Kugelschreiber vom Benni, aber der Kugelschreiber lag eindeutig an Incis Platz, nicht an dem von Benni, isch'schwör. Man könnte sich natürlich jetzt auf den Standpunkt stellen, daß ein Kuli an sich schon ein gewisses phallisches Potential hat, aber wenn ich ein Marketingmensch bei Pfizer wäre, würden mir durchaus phantasievollere Kugelschreiberformfaktoren einfallen.

Auch interessant: Der Beweis, daß ohne den DEI gar nichts geht, wenn schon unser SGL auf der Suche nach ihm swingtanzenderweise Kurs auf Mission Control nimmt:

Und das, obwohl sowohl Kreationisten (mein braver, treuer Deputy) wie Quartisten (meine bescheidene Wenigkeit) das in seltener Einmut verboten haben, wie unser Emailleschild eindeutig belegt:

Aber den X-Wing abgeschossen hat heute Anne-kin Fischer. Über sie haben wir in diesem Zusammenhang schon in der Vergangenheit berichtet. Doch als bedürfte es noch weiterer Beweise, daß sich in der hoffnungsvollen jungen Jedi, die sich zu unserem allergrößten Bedauern so sehr zur dunklen Seite der Macht hingezogen fühlt, so allmählich die Verwandlung zu Darth Ännchen vollzieht, ist sie heute mit echten Star-Wars-Stormtrooper-Boots bei επτ€σ aufgeschlagen:

Und weil man uns das nicht glaubt und uns morgen wieder jeder unterstellt, wir hätten das Bild aus irgendeinem Leder-Fetisch-Webshop geklaut, hier das ganze in der Totalen:

Deutlich erkennbar hat sie den fiesen Blick des mit der geballten Faust auf Rache für Padmé sinnenden Anakin Skywalker schon perfekt drauf. Wahrscheinlich hat sie das mit diesem Bild geübt. Mission Control muß sich vorsehen - vielleicht brauchen wir noch mehr Laserschwerter.

(Ein Klick auf ein Bild lädt es in höherer Auflösung in einem separaten Browserfenster)
(Edited: Der Link fuer Darth Ännchens Vorbild-Bild war a bissal flaky und ist jetzt durch einen hoffentlich robusteren ersetzt worden)

Dialoge aus credui.dll benutzen...

So, der ist jetzt für den Löselic, wie versprochen.

Irgendwie gewinne ich den Eindruck, als hätte sich noch nicht überall rumgesprochen, daß unter XP und seinen Nachfolgern die Möglichkeit besteht, die Authentifizierungsdialoge des Systems, ähnlich den "Common Dialogs" aus comdlg32.dll, auch für das UI der eigenen Programme zu benutzen.

Aussehen kann das dann etwa so:

Credui Beispiel

Und der Code, der dazu erforderlich ist (ein VC6-Projekt kann man hier runterladen), ist wirklich trivial:

#include <windows.h>
#include <wincred.h>
#include <tchar.h>
#include <stdio.h>

#ifndef dimof
#define dimof(a) (sizeof(a)/sizeof(a[0]))
#endif // dimof


int _tmain(int /*argc*/, LPCTSTR * /*argv*/ [])
{

    TCHAR szUser[CREDUI_MAX_USERNAME_LENGTH+1];
    ULONG ulUserMaxChars = dimof(szUser);
    TCHAR szPwd[CREDUI_MAX_PASSWORD_LENGTH+1];
    ULONG ulPwdMaxChars = dimof(szPwd);
    BOOL bSaveState = FALSE;
    DWORD dwFlags = CREDUI_FLAGS_DO_NOT_PERSIST|
                    CREDUI_FLAGS_GENERIC_CREDENTIALS|
                    CREDUI_FLAGS_ALWAYS_SHOW_UI;
    szUser[0] = szPwd[0] = _T('\0');


    if (NO_ERROR == CredUIPromptForCredentials
        (NULL, _T("this bloody Computer!"), NULL, ERROR_SUCCESS, 
         szUser, ulUserMaxChars, szPwd, 
         ulPwdMaxChars, &bSaveState, dwFlags))
        _tprintf(_T("You typed:\nuser: %s\npassword:%s\n"), 
                     szUser, szPwd);
    else
        _tprintf(_T("You idiot, you cancelled this dialog!\n"));


    return 0;
}

...und voila, man hat einen richtig amtlichen Windows-Authentifizierungsdialog. Wenn man jetzt noch total TSUnami-mäßig drauf ist, kann man den Dialog sogar noch a bissal pimpen und ihm im Header ein mehr oder minder hübsches Bitmap unterjubeln, um so das eigene CD auch noch zu verbreiten. Ich glaube allerdings, daß damit der Effekt des offiziell amtlichen Authentifizierungsdialogs doch ein wenig verloren geht. YMMV.

Das einzige, worauf man wirklich achtgeben muß, ist, daß das so nur unter XP und höher funktioniert. Wenn der Code auch unter Windows 2000 und NT4 funktionieren muß, muß man folgendes ergänzen:

  • Alternativcode mit einem eigenen Dialogtemplate, das verwendet wird, wenn die credui.dll nicht geladen werden kann
  • Delayload von credui.dll

Das Codebeispiel hier benutzt das CredUIPromptForCredentials API natürlich nur in einer äußerst generischen Form. Man kann mit diesem API aber auch einen Credentials Store des Betriebssystems benutzen und noch andere Gimmicks und Spielereien, aber ich hatte ehrlich gesagt noch nie das gesteigerte Bedürfnis, da näher nachzuforschen. Und ja, mit VC6 "out-of-the-box" geht das alles natürlich auch nicht, man braucht mindestens das Windows XP PlatSDK von 2001.

This news just in...

Es gibt ein paar bemerkenswerte Neuigkeiten aus επτ€σ Mission Control. Zum einen haben wir jetzt ein absolut hochoffizielles Türschild mit "Mission Control" drauf, unseren Namen, und unseren Dienstgraden, nämlich für mich den EMCSC und für meinen treuen Deputy den EMCSCD. Die Abkürzungen stehen natürlich für επτ€σ Mission Control Supreme Commander und επτ€σ Mission Control Supreme Commander Deputy. Und so schaugt das Türschild aus, für den Fall, daß uns das 'mal wieder keiner abnimmt:


Tausend Dank für dieses tolle Türschild schuldet Mission Control dem unermüdlichen Darth Ännchen. Ännchen ist einfach Supersonderextraklasse, auch wenn sie manchmal unter Apostrophenkatastropheritis leidet. Schade nur, daß ich irgendwie so ein komisches Gefühl im Urin habe, als ob es Mission Control in seiner jetzigen Form nimmer lang geben wird. Aber dazu mehr wenn irgendwas spruchreif wird.

Als nächstes hätten wir eine echte Innovation in Mission Control. Das bisherige Laserschwert, nunmehr ziemlich genau drei Jahre alt, hat einen kleinen, schicken Bruder bekommen. Genauer gesagt, haben wir jetzt ein Original Star Wars Merchandising Light Saber vom Typ "Obi Wan". Das macht erotisierende Lichteffekte und hat den Original Star Wars Light Saber Sound wie in den Filmen. Und wenn man jemanden mit dem Laserschwert trifft, geht ein kleiner Vibrator (huestel) in dem Laserschwert los. Da Mission Control ja eigentlich aus zwei gestandenen Elektrotechnikingenieuren besteht, könnte vielleicht sein, daß wir das Ganze noch a bissal pimpen und zusätzlich ein Elektroschockfeature einbauen. Aber dieses Feature müssen wir erst noch "schneiden" und dann einen "Domain Walkthrough" machen (oder andersrum? Ach egal...).

Auf jeden Fall, without any further ado, hier mein treuer Deputy mit dem alten Laserschwert:


... und hier mit dem neuen Laserschwert:


Schließen möchte ich dieses Blogposting mit den weisen Worten eines der gegenwärtig ca. 300 hochbegeisterten Lesern dieses Blogs, der mir in einer Email zu meiner 10.000€-Frage Folgendes ins Stammbuch schrieb:

"Wahrscheinlich kann man das auch nur verstehen, wenn man sich wie ein kleines Kind freuen kann, wenn EMCSC auf seinem Türschildchen steht."

 

Und das trifft die Sache so ziemlich haargenau ins Schwarze.

<< 1 ... 36 37 38 39 40 41 42 43 44 45 46 47 >>