Post aus Libyen

Assalamo Alaikum,

Wasalaam to you,and how are you doing?. My intention of contacting you is to solicit your assistance for a project which will be mutually beneficial. Though I know my decision to contact you is to a large extent unconventional, the prevailing circumstances necessitated my action.

I am ZAINAB ABDULKARIM from Libya. I am married to Late Mallam USMAN ABDULKARIM of blessed memory was an oil explorer in Libya and Kuwait for twelve years before he died in the year 2000. We were married for twelve years without a child. He died after a brief illness that lasted for only four days. Before his death we were both devoted Muslims. Since his death I too have been battling with both Cancer and fibroid problems. When my late Husband was alive he made a huge deposit in millions of US dollars with a Deposit Company in oversea. (I will tell you the amount as we proceed).

Recently, my doctor told me that I have only six months to live due to cancer problem. Though what disturbs me most is my stroke sickness. Having known my condition I decided to donate this fund to either a Muslim organization or devoted Muslim individual that will utilize this money the way I am going to instructs herein. I want this Muslim organization or individual to use this money in all sincerity to fund mosques, orphanages, widows, and also propagating the word of ALLAH and to ensure that the society upholds the views and belief of the Holy Quran.

The Holy Quran emphasizes so much on ALLAH’S benevolence and this has encourage me to take the bold step. I took this decision because I don’t have any child that will inherit this money and my husband relatives are into some radical organisations and I don’t want a situation where this money will be used in an Unholy manner. Hence the reasons for this bold decision. I know that after death I will be with ALLAH the most beneficient and the most merciful.

I don’t need any telephone communication in this regard because of my health, because of the presence of my husband’s relatives around me always. I don’t want them to know about this development. With ALLAH all things are possible. As soon as I receive your reply on Email: hajiazainab027@yahoo.com, I shall give you the contact information of the Deposit Company in oversea where the money was deposited. I will also issue a letter of authority to the Deposit Company authorizing them that the said fund Have being willed to you and a copy of such authorization will be forwarded to you. I want you and the Muslim community where you reside to always pray for me. My happiness is that I lived a true devoted Muslims worthy of emulation. Whoever that wants to serve ALLAH must serve him in truth and in fairness. I will not stipulate any precise amount to reward you as it will have to be on pre-negotiated terms,based on your level of involvment.Please always be prayerful all through your life. Any delay in your reply will give room in sourcing for a Muslim organization or a devoted Muslim for this same purpose. Until

I hear from you by email, my dreams will rest squarely on your shoulders. May the Almighty ALLAH continue to guide and protect you.

Allah Hafiz.
HAJIA ZAINAB ABDULKARIM.

Zurück zum Standard

Nach Informationen auf golem.de stellt Microsoft wieder zwei neue Tastaturen vor. Bemerkenswert ist, dass auf den Screenshots der Block über den Cursortasten (Einfg, Entf, Pos1, Ende, BildAuf und BildAb) nun [b]endlich[/b] wieder so angeordnet ist, wie es eigentlich schon seit Jahrzehnten üblich ist. In der letzten Modellreihe wurde der Block einfach um 90° gedreht, die Entf-Taste auf zwei Tasten vergrößert und die Einfg-Taste noch eine Reihe nach oben verschoben. Jeder, der noch mit den Tastenkürzeln Strg+Einfg und Umschalt+Einfg aufgewachsen ist, konnte damit überhaupt nicht arbeiten.

Derzeit nutze ich immer noch das Natural Keyboard Pro, das es leider schon seit über zwei Jahren nicht mehr zu kaufen gibt. Dank einer intensiven Grundreinigung präsentieren sich meine Tastaturen aber nun wieder wie am ersten Tag und so gibt es wohl keinen Grund, den Tippuntersatz zu erneuern.

Für ein selbständiges Bayern

Vorgestern habe ich im ZDF (oder war es doch in der ARD?) einen Werbespot zur Bundestagswahl von der Bayernpartei gesehen. Nun habe ich mir mal die Website angeschaut, und ich bin schwer begeistert. Schade, dass diese Partei nur in Bayern antritt. Ich bin mir sicher, dass die Bayernpartei gerade nach den Äußerungen von König Edmund dem 1. in den letzten Wochen auch außerhalb Bayerns mit vielen Stimmen rechnen könnte.

Aber das mit dem Rechnen müsst ihr noch üben… ;)

Bayern im europäischen Vergleich

Schöner testen

In den letzten beiden Tagen habe ich den Dialog, der beim Programmstart auf die 60-Tage-Testversion hinweist, ein wenig runderneuert. Alexandra hatte wieder einmal eine tolle Idee, wie man diesen Dialog etwas frischer und moderner gestalten kann. Zusätzlich zu der Fortschrittsanzeige mit den ablaufenden Tagen zeigt nun auch ein passender Farbverlauf, dass die Testzeit langsam zu Ende geht.

Erstes Drittel

Nach dem ersten Drittel erscheint das Fenster nun in einem Gelbton.

Zweites Drittel

Das letzte Drittel der Testzeit wird dann rötlich dargestellt.

Letztes Drittel

GetMenuItemInfo und x64

Das Platform SDK enthält alle (dokumentierten) Definitionen der Windows-API, die für die Entwicklung von Windows-Anwendungen nötig sind. Im Laufe der Zeit und der vielen Windows-Versionen kommen immer wieder ein paar neue Definitionen hinzu, häufig werden ältere Definitionen auch erweitert. Damit die Windows-Version, auf dem die Anwendung dann läuft, auch weiß, wie groß die Strukturdaten sind, die bei einem Aufruf einer API-Funktion übergeben werden, enthält eine Strukturdefinition in den meisten Fällen als ersten Wert die Größe der Struktur. So kann das Betriebssystem entscheiden, welche Daten in der Struktur gültig sind und von welchen Daten es zwecks Vermeidung eines Zugriffsfehlers die Finger lassen sollte.

In der Regel läuft das alles auch problemlos, eine recht heikle Funktion ist aber GetMenuItemInfo im Zusammenhang mit der MENUITEMINFO-Struktur:

typedef struct tagMENUITEMINFO
{
    UINT     cbSize;
    UINT     fMask;
    UINT     fType;         // used if MIIM_TYPE (4.0) or MIIM_FTYPE (>4.0)
    UINT     fState;        // used if MIIM_STATE
    UINT     wID;           // used if MIIM_ID
    HMENU    hSubMenu;      // used if MIIM_SUBMENU
    HBITMAP  hbmpChecked;   // used if MIIM_CHECKMARKS
    HBITMAP  hbmpUnchecked; // used if MIIM_CHECKMARKS
    ULONG_PTR dwItemData;   // used if MIIM_DATA
    LPSTR    dwTypeData;    // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
    UINT     cch;           // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
#if(WINVER >= 0x0500)
    HBITMAP  hbmpItem;      // used if MIIM_BITMAP
#endif /* WINVER >= 0x0500 */
}   MENUITEMINFO, FAR *LPMENUITEMINFO;

Diese Struktur wurde für Windows 2000 und Windows ME erweitert, wie man an

#if(WINVER >= 0x0500) 
    HBITMAP hbmpItem; // used if MIIM_BITMAP 
#endif /* WINVER >= 0x0500 */ 

sieht. Durch das Makro WINVER lässt sich steuern, ab welcher Windows-Version die Anwendung laufen soll. Dieses und einige weitere Makros sind über die ganzen API-Definitionen verstreut. Definiert man WINVER z.B. mit 0×0400, damit die Anwendung auch unter Windows 95 und NT 4 lauffähig ist, werden sämtliche zusätzliche Definitionen ausgeblendet. Dies hat aber den Nachteil, dass man neue Funktionen und Flags überhaupt nicht mehr benutzen kann.

Daher setze ich WINVER immer auf 0×0501 und importiere Funktionen, die erst ab einer bestimmten Windows-Version verfügbar sind, immer dynamisch. Somit laufen meine Anwendungen alle ab Windows 95/NT4, sofern zumindestens der Internet Explorer 5.5 installiert ist. Dieser enthält einige wichtige Systemerweiterungen, die von Entwicklerseite nicht einzeln redistributierbar sind.

Bei der Funktion GetMenuItemInfo gibt es aber einen kleinen Stolperstein. Übergibt man hier als Strukturgröße in cbSize die neue Größe, dann verweigern Windows 95 und NT4 mit der Fehlermeldung 87 (Ungültiger Parameter) die Arbeit. Beide Systeme verlangen explizit die alte und ihnen bekannte Strukturgröße ohne das zusätzliche hbmpItem.

Als Workaround hatte ich mir daher vor langer Zeit einmal ein paar Definitionen zusammengestellt, mit deren Hilfe dieses Problem umgangen wird:

#define MENUITEMINFO_SIZE_VERSION_400A  CDSIZEOF_STRUCT(MENUITEMINFOA, cch)
#define MENUITEMINFO_SIZE_VERSION_400W  CDSIZEOF_STRUCT(MENUITEMINFOW, cch)
#define MENUITEMINFO_SIZE_VERSION_500A  sizeof(MENUITEMINFOA)
#define MENUITEMINFO_SIZE_VERSION_500W  sizeof(MENUITEMINFOW)

#ifdef UNICODE
    #define MENUITEMINFO_SIZE_VERSION_400  MENUITEMINFO_SIZE_VERSION_400W
    #define MENUITEMINFO_SIZE_VERSION_500  MENUITEMINFO_SIZE_VERSION_500W
#else
    #define MENUITEMINFO_SIZE_VERSION_400  MENUITEMINFO_SIZE_VERSION_400A
    #define MENUITEMINFO_SIZE_VERSION_500  MENUITEMINFO_SIZE_VERSION_500A
#endif

#define MENUITEMINFO_SIZE		MENUITEMINFO_SIZE_VERSION_400

Da ich die zusätzliche Strukturvariable hbmpItem fast nie benötige, verwende ich für die Größe der Struktur in cbSize immer MENUITEMINFO_SIZE, somit funktioniert die Funktion problemlos auf allen Systemen ab Windows 95.

Beim Testen der x64-Version vom SpeedCommander musste ich aber leider feststellen, dass nun Windows XP x64 an dieser Stelle herumzickt. Alle Aufrufe von GetMenuItemInfo wurden wieder mit Fehler 87 zurückgegeben. Ändert man die Strukturgröße jedoch auf MENUITEMINFO_SIZE_VERSION_500, dann funktioniert es unter Windows XP x64 wieder wie erwartet. Eine kleine Erweiterung der obigen Definition schafft Abhilfe:

#define MENUITEMINFO_SIZE_VERSION_400A  CDSIZEOF_STRUCT(MENUITEMINFOA, cch)
#define MENUITEMINFO_SIZE_VERSION_400W  CDSIZEOF_STRUCT(MENUITEMINFOW, cch)
#define MENUITEMINFO_SIZE_VERSION_500A  sizeof(MENUITEMINFOA)
#define MENUITEMINFO_SIZE_VERSION_500W  sizeof(MENUITEMINFOW)

#ifdef UNICODE
    #define MENUITEMINFO_SIZE_VERSION_400  MENUITEMINFO_SIZE_VERSION_400W
    #define MENUITEMINFO_SIZE_VERSION_500  MENUITEMINFO_SIZE_VERSION_500W
#else
    #define MENUITEMINFO_SIZE_VERSION_400  MENUITEMINFO_SIZE_VERSION_400A
    #define MENUITEMINFO_SIZE_VERSION_500  MENUITEMINFO_SIZE_VERSION_500A
#endif

#ifdef _M_IX86
    #define MENUITEMINFO_SIZE		MENUITEMINFO_SIZE_VERSION_400
#else
    #define MENUITEMINFO_SIZE		MENUITEMINFO_SIZE_VERSION_500
#endif

Beim Kompilieren für 32bit-Systeme wird wie bisher immer die Größe der alten Struktur verwendet, beim Kompilieren für 64bit-Systeme dagegen die Größe der neuen Struktur.

hackbsd Crew 0wnz y0u! @ jank0

So stand es heute Mittag hier auf dieser Seite. Ursache für den Hack ist anscheinend eine Sicherheitslücke in WordPress 1.2. Es gibt zwar bereits seit April eine Version 1.5, zwei Dinge haben mich aber bisher vom Update zurückgehalten. Zum einen war ich mit der 1.2 vollkommen zufrieden und zum anderen wurde mit der 1.5 der Unterbau ziemlich geändert, so dass einige Arbeiten am mühsam gebastelten Layout zu erwarten gewesen wären.

Wie es ausschaut, war mein Blog nicht das erste Opfer. Nun blieb mir leider nichts anderes übrig, als WordPress 1.5 zu installieren. Das Update selbst geschah per Script völlig problemlos, aber dann ging der K(r)ampf wie erwartet los. Sämtliche permanente Links funktionierten nicht mehr, weil WordPress 1.5 das ‘index.php’ in den Links entfernt. Zwar kann man in der ‘.htaccess’ wohl ein paar Rewrite-Konditionen setzen, aber ich habe es nicht geschafft, mich mit Erfolg durch die Hilfe zu kämpfen. Im WordPress-Forum fand ich dann eine einfache Lösung, mit der es wieder wie vorher funktioniert. In der Datei ‘wp-includes/template-functions-links.php’ müssen alle sechs Vorkommen von ‘/?’ durch ‘/index.php?’ ersetzt werden.

Knappe zwei Stunden habe ich dann noch gebraucht, bis sich die Seite wieder im gewohnten Layout präsentierte. Sollte ich noch etwas vergessen haben, dann würde ich mich über eine Nachricht freuen. Ansonsten macht WordPress 1.5 bisher einen sehr guten Eindruck. Es bietet nun auch einen eingebauten Spamschutz für Kommentare, dieser beschränkt sich aber nur darauf, verdächtige Kommentare zur Moderation vorzumerken. Unbedingt empfehlenswert ist daher die Installation von Spam Karma 2, dessen Vorversion mir schon große Dienste erwiesen hat. Seit Anfang des Jahres wurden hier knapp 1300 Kommentare abgelegt, von denen lediglich 166 durch reale Leser geschrieben wurden. Der Rest stammt von Spam-Bots, die für Onlinepoker und sonstige Sachen werben.

Heureka

Ein großes Produktivitätshemmnis in Visual Studio 2005 ist für mich das Suchen- und Ersetzen-Fenster. Im Gegensatz zu früheren Versionen wird dieses Fenster nun als normales Dokumentenfenster innerhalb der geöffneten Quelltextdateien angezeigt. Das Suchen und Ersetzen wird somit zur Qual, da man während der Eingabe des Suchstrings den Quelltext aus den Augen verliert.

Suchen- und Ersetzen-Fenster

Trotz des intensiven Durcharbeitens aller Einstellungsdialoge konnte ich keine Möglichkeit finden, wie man dieses Fenster deaktivieren und wieder den normalen Dialog verwenden kann. Beim Debuggen auf dem x64-Rechner blinzelte mich plötzlich der gewohnte Dialog an, ich fand zuerst keine Erklärung, warum auf dem einen Rechner das Suchfenster und auf dem anderen der Dialog angezeigt wurde. Zufällig klickte ich dann mit der rechten Maustaste auf die Titelzeile des Dialoges und fand die verzweifelt gesuchte Einstellung:

Suchen- und Ersetzen-Dialog

Falsch multipliziert

Beim Debuggen von SpeedCommander unter x64 bin ich auf einen unschönen Bug in der ATL vom Visual Studio 2005 gestoßen. Während des Einlesens der Symbolleisten-Einstellungen wurde eine Exception geworfen und SpeedCommander stürzte ab. Nach dem Durchkämpfen bis zum Auslöser der Exception war der Fehler auch recht schnell sichtbar.

Die Exception wurde nach der Funktion AtlMultiplyThrow ausgelöst. AtlMultiplyThrow wird beim Reservieren eines Speicherbereichs aufgerufen und dient dazu, die Größe des zu reservierenden Speicherbereichs aus einer Anzahl von Elementen und deren Blockgröße zu ermitteln. Der Parameter tLeft gibt in diesem Fall die Anzahl der zu reservierenden Elemente und der Parameter tRight die Blockgröße an:

template <typename T>
inline T AtlMultiplyThrow(T tLeft, T tRight)
{
    T tResult;
    HRESULT hr=AtlMultiply(&tResult, tLeft, tRight);
    if(FAILED(hr))
    {
        AtlThrow(hr);
    }
    return tResult;
}

AtlMultiplyThrow ruft lediglich AtlMultiply auf, im Fehlerfall wird eine Exception ausgelöst:

/* generic but compariatively slow version */
template<typename T>
inline HRESULT AtlMultiply(T* ptResult,	T tLeft, T tRight)
{
    /* avoid divide 0 */
    if(tLeft==0)
    {
        return 0;
    }
    if(::ATL::AtlLimits<T>::_Max/tLeft < tRight)
    {
        return E_INVALIDARG;
    }
    *ptResult= tLeft * tRight;
    return S_OK;
}

Der Fehler tritt nur auf, wenn der Wert tLeft Null ist. In diesem Fall gibt AtlMultiply 0 zurück, was auch der Wert für S_OK ist. AtlMultiplyThrow wird erfolgreich verlassen und gibt den Wert von tResult zurück. Wenn man sich die beiden Funktionen nun etwas genauer anschaut, dann entdeckt man, dass der Inhalt von tResult undefiniert ist. In der Debugversion werden alle Werte automatisch mit 0xCCCCCCCC initialisiert, somit gibt AtlMultiplyThrow hier 3435973836 zurück.

Die Allokation des Speichers erfolgt beim Einlesen der Einstellungen, genauer gesagt wenn ein String geladen wird. In der entsprechenden MFC-Funktion wird Speicher entsprechend der Zeichen im String reserviert. Für einen leeren String werden 0 Bytes reserviert, durch den Bug in der Berechnung soll Windows allerdings knapp 3.5 GB bereitstellen. Das kann natürlich nicht gut gehen.

Die Korrektur ist sehr einfach, in der Funktion AtlMultiply muss lediglich die Variable ptResult genullt werden, wenn tLeft den Wert 0 enthält:

/* generic but compariatively slow version */
template<typename T>
inline HRESULT AtlMultiply(T* ptResult,	T tLeft, T tRight)
{
    /* avoid divide 0 */
    if(tLeft==0)
    {
        *ptResult = 0;
        return S_OK;
    }
    if(::ATL::AtlLimits<T>::_Max/tLeft < tRight)
    {
        return E_INVALIDARG;
    }
    *ptResult= tLeft * tRight;
    return S_OK;
}

Abschließend muss die MFC zwingend neu kompiliert werden, da der Fix ansonsten nur für eigene Anwendungen gilt und nicht für Funktionen innerhalb der MFC.

Standards fordern und selbst nicht einhalten

Paul Thurrot fordert in seinem Blog auf, den Internet Explorer 7 zu boykottieren, weil er unsicher sei und keine Standards einhält. Dies macht ihn für Anwender und Web-Entwickler unbenutzbar. Anlass dafür ist die Aussage von IE-Produktmanager Chris Wilson, dass auch die finale Version vom IE7 den Acid2-Test nicht bestehen wird. Im übrigen besteht nur eine speziell angepasste Version von Safari diesen Test, alle anderen Browser (Firefox, Opera) scheitern ebenso.

Vielleicht sollte sich Paul Thurrot erst einmal um seine Website kümmern, bevor er lauthals von anderen die Einhaltung von Standards fordert. Der w3C-Validator zeigt hier stolze 270 Fehler. Paul Thurrot sollte daher froh sein, dass seine Seite von den Browsern überhaupt angezeigt wird.

Grenzgänge

Unter Windows XP x64 erfolgt eine konsequente Trennung zwischen 32bit-Anwendungen und nativen 64bit-Anwendungen. Eine 64bit-Anwendung kann keine 32bit-Dll laden – damit haben momentan alle Entwickler zu kämpfen, die ihre 32bit-Module in das Kontextmenü des 64bit-Explorers einbinden möchten. Die einzige Lösung hierfür ist, die Shellerweiterung als 64bit-Version zu kompilieren.

Auf ein ähnliches Problem stößt man, wenn man eine native 64bit-Anwendung ausliefern möchte und einige Module nur als 32bit-Dll zur Verfügung stehen. Wenn die Module nicht überlebenswichtig sind, kann man sie vorerst auch ausklammern. Ein Beispiel hierfür ist Squeez, der in der 64bit-Ausgabe keine Anzeige von Bildern in der Schnellansicht erlaubt und auch keine ACE-Archive entpacken kann. Von den WinACE-Entwickler war bisher leider noch nicht zu erfahren, ob bzw. wann eine x64-Fassung der UnAceV2.dll zu erwarten ist. Mit der zunehmend immer geringeren Verbreitung von ACE-Archiven lässt sich die fehlende UnACE-Unterstützung aber sicher verschmerzen.

Ganz anders sieht es mit der Schnellansicht von Bildern aus, die im SpeedCommander noch eine sehr viel größere Bedeutung hat. Hierfür verwende ich seit einigen Jahren die PictView-Dll von Jan Patera. Diese Dll kann über 50 verschiedene Bildformate lesen und ist gerade einmal 191KB groß. Auf meine Anfrage zu einer x64-Version teilte mir Jan leider mit, dass er vorerst keine Umsetzung auf 64bit plane. Die Dll selbst benutzt viel Assemblercode, so dass eine Portierung auch nicht ganz einfach ist.

Beim Stöbern in der MSDN-Library entdeckte ich folgenden Satz:

On 64-bit Windows, a 64-bit process cannot load a 32-bit dynamic-link library (DLL). Additionally, a 32-bit process cannot load a 64-bit DLL. However, 64-bit Windows supports remote procedure calls (RPC) between 64-bit and 32-bit processes (both on the same computer and across computers). On 64-bit Windows, an out-of-process 32-bit COM server can communicate with a 64-bit client, and an out-of-process 64-bit COM server can communicate with a 32-bit client. Therefore, if you have a 32-bit DLL that is not COM-aware, you can wrap it in an out-of-process COM server and use COM to marshal calls to and from a 64-bit process.

“Gesagt, tun getan” pflegte Onkel Hotte immer zu sagen. Mit externen COM-Servern hatte ich bisher noch keinerlei Erfahrung, aber glücklicherweise bietet das Visual Studio 2005 mit der ATL dafür eine umfangreiche Unterstützung dafür. Ein COM-Server ist mit wenigen Handgriffen erstellt. Zusätzlich benötigt man noch eine Proxy-Dll, deren Projekt auch gleich generiert wird.

Das COM-Objekt definiert eine einfache Schnittstelle für den Zugriff auf die PictView-Dll. Es bekommt den Namen für die anzuzeigende Datei übergeben, lädt die Dll und bekommt dann von der Dll ein Bitmap (HBITMAP) zurück. Dieses wird in ein DIB (Device Independent Bitmap) konvertiert und an den Aufrufer zurückgegeben. Die Konvertierung in ein DIB ist notwendig, da das Marshaling zwischen dem externen COM-Server und dem Client bei einigen Grafiken nicht korrekt funktioniert, wenn ein HBITMAP übertragen wird. Vermutlich gibt es da noch einen kleinen Fehler im Windows-Marshaling-Code für HBITMAPs.

Damit ist nun auch die letzte große Hürde für die 64bit-Version von SpeedCommander genommen, die nun bis auf die fehlende UnACE-Unterstützung keinerlei Einschränkungen gegenüber der 32bit-Version mehr hat.