VS-2008/Orcas kommt jetzt doch erst im Februar 2008

KORREKTUR zu diesem Artikel hier
http://blog.m-ri.de/index.php/2007/07/17/rtm-fuer-vs-2008-orcas-doch-zum-ende-des-jahres/
Ich habe Launch und RTM durcheinander gebracht. Sorry!

„VS-2008/Orcas kommt jetzt doch erst im Februar 2008“ weiterlesen

Erstaunlich: const BYTE * != const LPBYTE

Erstaunlich! Wenn man die folgende Funktion kompiliert erhält man keine Fehlermeldung: 

void foo(const LPBYTE data)
{
    *data = 0; 
}

Man könnte denken, dass diese Funktion identisch wäre zu: 

void foo(const BYTE * data)
{
    *data = 0;        // Compiler Error
}

Ist es aber nicht! Die Funktion

void foo(const LPBYTE data);

ist identisch zu

void foo(BYTE * const data);

und eben nicht zu

void foo(const BYTE * data);

Der typedef darf selbst kein Zeiger sein! Er muss ein Basis Typ sein, nur dann führt const X * zum gewünschten Effekt.
Das ist das eigentliche Problem. Das entspricht auch mit dem Sample im Kapitel 5.4 der Stroustrup „C++ Bibel“.

Siehe auch Diskussion hier:
http://groups.google.de/group/microsoft.public.de.vc/browse_thread/thread/2568531dcf1c1d7e/215ead7f070e23d0

Wie kann ich das Visual Source Safe Kennwort zurücksetzen?

Ja! Dieses Kennwort braucht man selten, aber wenn man es braucht hat man es vergessen.
Aber die UM.DAT zu hacken ist ziemlich simpel. Es gibt einige Anleitungen im Netz dazu.
Hier meine Vaiante die man mit jedem x-beibigen Hexeditor verwenden kann

  • Man sucht an den Adressen 0x84, 0xC4, 0x104, etc. den Benutzernamen Admin.
  • Hat man die Adresse gefunden z.B. 0x84 (was meistens der erste Benutzer Eintrag ist), dann geht man 0x20 Bytes weiter. In meinen Beispiel gelangen wir nun an die Adresse 0xA4.
  • Hier ersetzen wir einfach die nächsten 4 Bytes durch:
    0x90 0x6e 0x00 0x00

Das Kennwort ist nun leer! Man kann ein neues vergeben. 

PS: Es gibt andere Tipps, die ersetzen hier 6 Zeichen. Das sollte man unterlassen, denn die nächsten beiden Zeichen sind eine interne user ID.

PPS: Die extreme Sicherheit des Source Safe Kennwortes ist erkennbar an dem immens sicheren Hasing auf 32bit! 😀 Eine Brute Force Attacke per Batch zu betreiben sollte auch kein Problem sein…

BTW: Der Hack ist natürlich auf eigene Gefahr und sollte nur gemacht werden, wenn man auch eine Sicherung der UM.DAT hat!

VSS Undo Checkout für einen Anwender den es nicht mehr gibt…

Da ist eine Datei die man ändern will. Man checkt sie aus und bekommt gesagt, dass diese Datei vom Benutzer „Wareinmal“ ausgecheckt ist.  😕 „Wareinmal“ war einmal bei uns beschäftigt… Lange her. Rechner wurde schon recycled.

Im Source Safe Explorer bekomme ich einen Undo Checkout für diese Dateien nicht angeboten. Und nun?
Im Dunkeln erinnere ich mich an ein Admin Kennwort für Visual Source Safe.

  • Also Source Safe Explorer so starten:
    SSEXP -yAdmin
  • Kennwort eingeben.
  • Datei suchen.
  • Undo Checkout…

Fertig!

Code Monkeys auch überall bei uns…

Über den Code Project newsletter habe ich diesen Blog-Eintrag gefunden:
http://geekswithblogs.net/sdorman/archive/2007/06/29/Programming-for-the-masses.aspx

Ich sehe auch in den Deutschen Foren, in denen ich mich tummle genau die gleichen Tendenzen. Die Szene in den Online Foren und in den NNTP Gruppen hat sich ziemlich verändert.
Man trifft überall Massen an Code Monkeys!

  • Netiquette unbekannt
  • F1-Taste drücken und die Basics der MSDN lesen wird nicht gemacht
  • FAQ ansehen ist umständlich
  • Nichtmal die entsprechenden bekannten Suchbegriffe in Google einzugeben gelingt
  • Basiswissen über die entsprechenden Programmiersprachen wird per Try&Error erprobt
  • Es zählt nur der schnelle Erfolg, auch wenn die Art und Weise wie die Lösung gefunden ist zweifelhaft ist
  • Grundsätzlich ist immer der Compiler und die verwendeten Libraries (CRT/MFC) buggy. Nie der eigene Code!

Irgendwie bin ich aus meiner Vergangenheit verwöhnt.
In meiner Anfangszeit als MVP habe ich weniger gepostet. Dafür waren die Antworten länger und ausführlicher, und meistens handelte es sich um wirkliche Probleme, die es zu lösen galt. Heute sind die Antworten weitaus kürzer und bestehen oft nur auf einen Verweis auf die Doku. Schade eigentlich. Man muss sich wirklich fragen warum man das eigentlich macht!

Im Großen und Ganzen hat sich das Niveau in der Newsgroup nntp://microsoft.public.de.vc gehalten. Allerdings ist die Gruppe der Poster und Regulars ziemlich geschrumpft. Es scheinen NNTP Gruppen irgendwie aus der Mode gekommen zu sein.

Foren wie http://www.c-plusplus.de/forum/index-var-.html und http://forums.microsoft.com/MSDN/default.aspx?SiteID=1 scheinen zu boomen, allerdings ist das Niveau hier nach unten offen…

Tja: Scheinbar war früher wirklich alles besser… 😉

VC-2005 Features der CRT für Unicode Unterstützung

Die CRT der VC-2005 hat eine perfekte Unterstützung für Unicode Dateien im UTF-8 und UTF-16 Little Endian Format.

Wollte man bisher Unicode Dateien lesen, so mussten diese mit _wfopen(…,L“rb“) geöffnet werden und entsprechende Leseoperationen mussten folgen. Um Unicode und ANSI Dateien zu unterscheiden schrieb man selbst entsprechenden Code, der nach einer BOM (Byte Order Mark) schaut. Beim Schreiben hatte man auch selbst darauf zu achten die BOM entsprechend zu setzen.

Ziemlich unbemerkt (auch von mir 🙂 ), hat die CRT hier eine entscheidene Erweiterung erfahren. Mit dem folgenden Code lässt sich gezielt jede Datei entsprechend öffnen und lesen, sofern Sie über eine korrekte BOM verfügt, bzw. auch eine Datei zum Schreiben öffnen die mit der entsprechenden BOM versehen wird.

FILE *pFile = _tfopen(_T(„myfile.txt“),_T(„rt, ccs=UNICODE“));

Ist die Datei eine ANSI Datei ohne BOM, wird sie entsprechend geöffnet. Unicode Dateien im Typ UTF-8 und UTF-16 little endian werden an der entsprechenden BOM erkannt und entsprechend gelesen.
Über ccs=UTF-8 bzw. ccs=UTF-16LE lässt sich auch gezielt eine entsprechende Unicode Datei ohne BOM öffnen. Eine vorhandene BOM überschreibt allerdings die beim Öffnen angegebenen Formatierung. Fein!

Leider hinkt die MFC diesen wirklich tollen Funktionen der CRT hinterher. Weder die MFC  8.0 aus VS-2005 noch die neue Orcas Version (Stand Beta1) verfügt über eine neue Version der CStdioFile, die diese Funktionen der CRT abbildet.

Glücklicherweise gibt es einen entsprechenden CStdioFile(FILE *) Konstruktor. Dadurch ist es möglich, einfach eine Datei mit _tfopen zu öffnen und den Stream einfach an ein CStdioFile Objekt zu koppeln.
Einziger Schönheitsfehler: CStdioFile::Close muss explizit in diesem Fall aufgerufen werden, d. h. Close wird nicht durch den Destruktor aufgerufen.
Für den MFC Kenner: m_bCloseOnDelete ist FALSE und leider protected. Dieses Flag verhindert, dass Close auch durch den Destruktor aufgerufen wird.

MSDN Dokumentation zu _tfopen/fopen/_wfopen

… und schließlich entdeckte Kolumbus SendDlgItemMessage

Wer hat nicht oft genug solchen Code geschrieben:

GetDlgItem(IDC_MYITEM)->SendMessage(WM_MYMSG,wParam,lParam);
// – oder-
HWND hWnd = ::GetDlgItem(hDlg,IDC_MYITEM);
if (hWnd)
    ::SendMessage(hWnd,WM_MYMSG,wParam,lParam);

Da programmiert man Jahrzente unter Windows und hat SendDlgItemMessage noch niemals gesehen und damit geht es so einfach:

SendDlgItemMessage(IDC_MYITEM,WM_MYMSG,wParam,lParam);
// – oder-
::SendDlgItemMessage(hDlg,IDC_MYITEM,WM_MYMSG,wParam,lParam);

Man lernt nie aus. 😉

MSDN Links: SendDlgItemMessage, CWnd::SendDlgItemMessage

BTW: Netter Seiteneffekt. Die direkte Verwendung von GetDlgItem(…)->SendMessage(…); ist natürlich äußerst unsicher. Im Extremfall kracht es. Charmant, dass SendDlgItemMessage sich hier äußerst robust und korrekt verhält.

MFC 8.0 PDB Dateien mit und ohne Source Informationen

Gestern hat es mich überrascht, dass ich beim debuggen auf einmal nicht mehr in eine MFC Funktion mit der F11 Taste steppen konnte. Er sprang immer über diese Zeile. Selbst über die Assembler Ansicht war es nicht möglich die entsprechenden Source-Dateien der MFC im Debugger durch zu steppen.

❓ Eigentümlich. Ein kurzer Blick in die Debug Ausgabe und in die Liste der geladenen Module zeigte, dass die PDB Datei der MFC80UD.DLL aus meinem Symbol-Cache geladen wurden.
In der Modulliste stand als Info: Symbols loaded (source information stripped).
Ich verwende einen zentralen Symbol Cache auf unserem Entwicklungsserver und habe natürlich auch als http://msdl.microsoft.com/download/symbols als Quelle für unbekannte Symbole angegeben.

Scheinbar ist auf irgend einem Weg vom Symbolserver aus dem Netz eine Version in meinen Cache hineingelangt, die nicht alle Debug Informationen enthält. Also gerade die Informationen, die es mir erlauben durch den Sourcecode der MFC zu steppen.

Die entsprechende Version mit den Source Informationen befindet sich durch die Installation von Visual Studio im Verzeichnis C:\Windows\Symbols\dll. Auch in den Optionen für mein Visual Studio war zusätzlich natürlich korrekt auch C:\Windows\Symbols\dll als Pfad angegeben. Die dortigen PDB Dateien wurden jedoch offensichtlich ignoriert. Ein manuelles Nachladen aus diesem Verzeichnis half allerdings sofort.
Bei der nächsten Debug Session wurden jedoch wieder die Informationen aus dem Cache geladen.

Also was machen?

❗ Ich habe einfach die entsprechenden Symbol aus dem C:\Windows\Symbols\dll Verzeichnis in meinen Symbol Cache geladen. Das geht einfach mit dem entsprechenden symstore Befehl:

symstore add /r /f C:\Windows\Symbols\dll\*.* /s <My symbol store>

Und siehe da. Nun werden immer die richtigen PDB-Dateien geladen und Step-Into Befehl F11 verhält sich beim debuggen wieder wie gewohnt.

Die Manifest Pest…

Hier noch mal ein paar wirklich nette Sachen, die zeigen warum ich Manifeste mittlerweile  nicht mehr ganz so mag (um es wirklich vorsichtig auszudrücken):

Was passiert eigentlich wenn man ein internes UND ein externes Manifest zu einer DLL oder EXE hinzufügt?

  1. Auf einem XP Rechner wird der Lader das externe Manifest bevorzugen, das interne Manifest wird ignoriert.
  2. Auf einem Windows 2003 oder Vista Rechner wird das interne Manifest bevorzugt und das externe Manifest wird ignoriert.
  3. Handelt es sich um eine DLL die mit LoadLibrary geladen wird, dann wird niemals ein externes Manifest berücksichtigt, selbst wenn kein internes Manifest vorliegt. Hier verhalten sich XP, 2003 und Vista gleich.

Ein Grund mehr zu meiner Empfehlung: Verwende immer nur interne Manifeste!

Was man beim Umstieg von VSS auf TFS bedenken muss!

Ich plane in der nächsten Zeit Visual Source Safe (VSS) abzulösen. Da wir alle Hauptprojekte (bis auf einigen legacy Kram) auf VC++ 2005 bearbeiten und die entsprechenden Visual Studio Team System Lizenzen haben beabsichtigen wir auch den Team Foundation Server (TFS) einzusetzen.
Einen Team Foundation Server kaufen müssen wir auch nicht, denn wir haben nicht mehr als 5 Clients.

Vorteile:

  • Integration auch in ältere Systeme ist kein Problem! Für VC6, VB6, VS.NET 2003 gibt es entsprechende Plug-Ins! Das ist schon mal genial. Also können wir theoretisch sogar alle legacy Projekte konvertieren und mit den alten Tools weiterarbeiten.
  • Alles wird in einem SQL-Server gehalten. Endlich!
  • Die Projekt Dokumente sind gleich in dem entsprechenden Share Point mit gehalten (leider noch WSS 2.0)
  • Einchecken mehrere Dateien werden direkt zu einem Vorgang zusammengefasst.
  • Direktes Bug-Tracking und einfache Projektierung ist möglich ohne externe Hilfsmittel.

Beim evaluieren der Features habe ich mir schon die Hände gerieben. Allerdings gibt es da eine wirkliche fette Kröte die ich schlucken muss. Mein geliebtes „Sharing“ unter VSS gibt es unter dem Source Control System von TFS nicht ❗

Wir haben einiges an gemeinsamen Code, den wir nicht in Libraries oder DLLs zusammengefasst haben. Da sind einige nette Template Klassen etc., spezielle Header und andere nette Code-Snipplets. Alle diese Code Teile waren in einem kleinen Projekt zusammengefasst und jeder Entwickler konnte diese wahlfrei in sein Projekt sharen. Das ist und war extrem bequem. Mit dem Drawback, dass eine zentrale Code Änderung alle Projekte beeinflusst und evtl. bricht kann man leben.
Man muss einfach regelmäßig Ohrfeigen verteilen für Entwickler die nicht testen und Kerker bei Brot und Wasser androhen… 😉

Unter TFS ist es damit vorbei. Einziger Ausweg wie ich ihn aktuell sehe ist es, die entsprechenden Codeteile einzubranchen in die anderen Projkete. D.h. aber das man die aktuelle Version (und den evtl. gewünschten Fix) nur mit einem Merge bekommt, was wieder nicht unbedingt automatisch geht, man muss also Hand anlegen was man evtl. eben auch vergisst.

Mal sehen vielleicht fällt mir da noch was anderes ein. Anonsten sieht das ganze sehr vielversprechend aus.