<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Martin&#039;s Blog &#187; Windows API</title>
	<atom:link href="http://blog.m-ri.de/index.php/category/programmieren/windows-api/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.m-ri.de</link>
	<description>Gesammeltes aus dem Leben eines &#34;normalen&#34; Programmierers... :-)</description>
	<lastBuildDate>Sat, 04 Feb 2012 12:07:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>OemToCharBuffW macht nicht das gleiche wie OemToCharBuffA und anschließender Umwandlung nach Unicode</title>
		<link>http://blog.m-ri.de/index.php/2011/08/22/oemtocharbuffw-macht-nicht-das-gleiche-wie-oemtocharbuffa-und-anschliesender-umwandlung-nach-unicode/</link>
		<comments>http://blog.m-ri.de/index.php/2011/08/22/oemtocharbuffw-macht-nicht-das-gleiche-wie-oemtocharbuffa-und-anschliesender-umwandlung-nach-unicode/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 17:20:13 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[Unicode]]></category>
		<category><![CDATA[WinAPI]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=892</guid>
		<description><![CDATA[Ein Stück Code in unserer Software behandelt Datenimport aus fremden Dateien. Nicht wenige alter DOS Programme erzeugen ja Daten im &#8220;OEM&#8221;-Zeichensatz (DBase etc.). Wir haben in der Vergangenheit immer streng die T-Notation verwendet und eigentlich sollte dies einen vor vielen Überraschungen bewahren. Aber Pustekuchen. Folgender Code sollte Daten aus einem OEM-Stream in einen CString umwandeln [...]]]></description>
			<content:encoded><![CDATA[<p>Ein Stück Code in unserer Software behandelt Datenimport aus fremden Dateien. Nicht wenige alter DOS Programme erzeugen ja Daten im &#8220;OEM&#8221;-Zeichensatz (DBase etc.).<br />
Wir haben in der Vergangenheit immer streng die T-Notation verwendet und eigentlich sollte dies einen vor vielen Überraschungen bewahren. Aber Pustekuchen.</p>
<p>Folgender Code sollte Daten aus einem OEM-Stream in einen <em>CString</em> umwandeln und eigentlich bin ich davon ausgegangen, dass das Ergebnis für Tabulatoren (&#8216;\t&#8217;) und Zeilenschaltungen (&#8220;\r\n&#8221;) ergebnisneutral ist. D.h. in anderen Worten ich erwartete in dem String genauso viele Tabulatoren und Zeilenschaltungen vor wie nach der Konvertierung.<br />
Die Umwandlung erfolgte mit solch einem Stück Code:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">CString strText<span style="color: #008080;">;</span>
<span style="color: #008080;">::</span><span style="color: #007788;">OemToCharBuff</span><span style="color: #008000;">&#40;</span>szText,CStrBuf<span style="color: #008000;">&#40;</span>srText,len<span style="color: #008000;">&#41;</span>,len<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>Sieht eigentlich harmlos aus. Allerdings musste ich feststellen, dass hier <em>OemToCharBuffA</em> und <em>OemToCharBuffW</em> ganz und gar nicht korrespondierende Ergebnisse liefern.<br />
In der Unicode Version, also in der Version die <em>OemToCharBuffW</em> verwendet, wurden Tabulatoren zu <em>0x25cb L&#8217;○&#8217; wchar_t </em> und Zeilenschaltungen zu <em>0x266a L&#8217;♪&#8217; wchar_t </em>und <em>0x25d9 L&#8217;◙&#8217; wchar_t!</em></p>
<p>Führt man jedoch zuerst eine Kovertierung in den &#8220;ANSI/Windows/8bit&#8221;-Zeichensatz durch und konvertiert anschließenend diesen ANSI-String nach Unicode, dann ist alles gut und so wie man es erwartet.</p>
<p>Wer Lust hat das nachzubauen kann das mit dem folgenden Code. Wichtig sind eigentlich nicht die OEM-Umlaute sondern nur die Tab- und Zeilenschaltungen:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span> szText<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;Dies ist ein OEM TestString<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
       <span style="color: #FF0000;">&quot;mit Zeilenschaltungen<span style="color: #000099; font-weight: bold;">\t</span>und Tabs<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
       <span style="color: #FF0000;">&quot;und Umlauten:<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
       <span style="color: #FF0000;">&quot;Ž=AE, ™=OE, š=šE<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
       <span style="color: #FF0000;">&quot;„=ae, ”=oe, =ue, á=ss&quot;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">const</span> <span style="color: #0000ff;">size_t</span> len <span style="color: #000080;">=</span> <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>szText<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
CStringW strOut1<span style="color: #008080;">;</span>
<span style="color: #008080;">::</span><span style="color: #007788;">OemToCharBuffW</span><span style="color: #008000;">&#40;</span>szText,CStrBufW<span style="color: #008000;">&#40;</span>strOut1,len<span style="color: #008000;">&#41;</span>,len<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
CStringA strOut2<span style="color: #008080;">;</span>
<span style="color: #008080;">::</span><span style="color: #007788;">OemToCharBuffA</span><span style="color: #008000;">&#40;</span>szText,CStrBufA<span style="color: #008000;">&#40;</span>strOut2,len<span style="color: #008000;">&#41;</span>,len<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
CStringW strOut3<span style="color: #008000;">&#40;</span>strOut2<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
_ASSERT<span style="color: #008000;">&#40;</span>strOut1.<span style="color: #007788;">Compare</span><span style="color: #008000;">&#40;</span>strOut3<span style="color: #008000;">&#41;</span><span style="color: #000080;">==</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Das sollte eigentlich gleich sein</span></pre></div></div>

<p lang="cpp">PS: Getestet habe ich das auf einem <em>Windows 7</em> 64bit und 32bit OS.</p>
<p lang="cpp">Siehe folgende Links zu den Begriffen OEM/ANSI:<br />
<a href="http://blogs.msdn.com/b/oldnewthing/archive/2005/10/27/485595.aspx">http://blogs.msdn.com/b/oldnewthing/archive/2005/10/27/485595.aspx<br />
</a><a href="http://blogs.msdn.com/b/oldnewthing/archive/2005/03/08/389527.aspx">http://blogs.msdn.com/b/oldnewthing/archive/2005/03/08/389527.aspx</a></p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2011/08/22/oemtocharbuffw-macht-nicht-das-gleiche-wie-oemtocharbuffa-und-anschliesender-umwandlung-nach-unicode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GetModuleFileName liefert nicht exakt den Namen der EXE/DLL Datei wie er auf der Platte steht</title>
		<link>http://blog.m-ri.de/index.php/2011/06/25/getmodulefilename-liefert-nicht-exakt-den-namen-der-exedll-datei-wie-er-auf-der-platte-steht/</link>
		<comments>http://blog.m-ri.de/index.php/2011/06/25/getmodulefilename-liefert-nicht-exakt-den-namen-der-exedll-datei-wie-er-auf-der-platte-steht/#comments</comments>
		<pubDate>Sat, 25 Jun 2011 16:46:47 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[WinAPI]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=820</guid>
		<description><![CDATA[Wir haben ein Stück Code, dass verhindern soll, dass ein Programm zweimal gestartet werden kann. Dieser basiert auf einem Mutex und einer Memory Mapped File, mit der man sich auch das Fenster-Handle einer bereits gestarteten Instanz besorgen kann. Nun gelang es einem unserer Händler aber dennoch dieses Programm zweimal in einer Session zu starten und zwar auf [...]]]></description>
			<content:encoded><![CDATA[<p>Wir haben ein Stück Code, dass verhindern soll, dass ein Programm zweimal gestartet werden kann.<br />
Dieser basiert auf einem Mutex und einer Memory Mapped File, mit der man sich auch das Fenster-Handle einer bereits gestarteten Instanz besorgen kann.</p>
<p>Nun gelang es einem unserer Händler aber dennoch dieses Programm zweimal in einer Session zu starten und zwar auf folgendem Weg:</p>
<ol>
<li>Er startet die Software mit dem normalen Link auf dem Desktop, der durch das Installationsprogramm angelegt wurde.</li>
<li>Er öffnen eine Console mit CMD.EXE und wechselt in das Verzeichnis, gibt den Programmnamen ein und das Programm startet erneut. <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_surprised.gif' alt=':eek:' class='wp-smiley' /> </li>
</ol>
<p>Die Ursache ist war wie folgt:</p>
<ol>
<li>Der Mutex den wir intern verwendet haben nutzte den Dateinamen der EXE. Der Name des Mutex wird unter Anderem auch durch <em>GetModuleFileName</em> ermittelt.</li>
<li>Der Dateiname der EXE, wenn sie als Verknüpfung gestartet wird ist &#8220;XYZ.exe&#8221; (so wie die Datei auch auf der Festplatte heißt) und das liefert auch <em>GetModuleFileName</em> als Ergebnis.</li>
<li>Der Dateiname, den <em>GetModuleFileName</em> liefert, wenn man das Programm aus CMD.EXE startest ist exakt so wie man es eintippt, also z.B. &#8220;xyz.exe&#8221;. Erstaunlich.</li>
<li>Da der <a href="http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx" target="_blank">Mutex </a>einen Namen case sensitiv behandelt (was ich nicht vermutet hätte und erst mit staunenden Augen nachgelesen habe), wurde das bereits gestartete Programm nicht erkannt und eine zweite Instanz gestartet.</li>
</ol>
<p>Was schreiben wir uns also hinter die Löffel für die Zukunft:<br />
a) <em>GetModuleFileName</em> liefert nicht den &#8220;exakten&#8221; Dateinamen (obwohl ich es anders erwartet hätte)!<br />
b) Mutexe sind case sensitiv wie auch Events (obwohl ich hier eine Behandlung wie bei einem Dateinamen erwartet habe)!<br />
c) Manche Erwartungen trügen&#8230; <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2011/06/25/getmodulefilename-liefert-nicht-exakt-den-namen-der-exedll-datei-wie-er-auf-der-platte-steht/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Auf was man unbedingt achten muss, wenn man an Manifesten für Assemblies herumbastelt</title>
		<link>http://blog.m-ri.de/index.php/2011/04/25/auf-was-man-unbedingt-achten-muss-wenn-man-an-manifesten-fur-assemblies-herumbastelt/</link>
		<comments>http://blog.m-ri.de/index.php/2011/04/25/auf-was-man-unbedingt-achten-muss-wenn-man-an-manifesten-fur-assemblies-herumbastelt/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 18:34:08 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Vista / Windows 7]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Manifest]]></category>
		<category><![CDATA[SxS]]></category>
		<category><![CDATA[WinSxS]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=810</guid>
		<description><![CDATA[Ich habe für ein Projekt Manifeste zur Verwendung von Registration-Free COM Module gebaut. Diese COM-Module wurden über ein Manifest in einer EXE geladen. Natürlich hatte jedes der COM Module wieder ein eigenes Manifest, die ich entsprechend angepasst habe. Jede COM-Class, die verwendet wird, muss ja in dem Manifest der DLL-Assembly aufgeführt werden. Eigentümlich war, dass [...]]]></description>
			<content:encoded><![CDATA[<p>Ich habe für ein Projekt Manifeste zur Verwendung von <a href="http://msdn.microsoft.com/en-us/magazine/cc188708.aspx">Registration-Free COM Module</a> gebaut.</p>
<p>Diese COM-Module wurden über ein Manifest in einer EXE geladen. Natürlich hatte jedes der COM Module wieder ein eigenes Manifest, die ich entsprechend angepasst habe. Jede COM-Class, die verwendet wird, muss ja in dem Manifest der DLL-Assembly aufgeführt werden.</p>
<p>Eigentümlich war, dass ich nach Änderungen der Manifeste und auch nachdem das COM Modul komplett neu gelinkt wurde, dennoch die EXE ihr Ladeverhalten nicht geändert hat. Manche COM-Klassen wurden nicht gefunden. Sobald ich aber den Rechner neu gestartet hatte funktionierte ab dann alles wie gewünscht und das geänderte Manifest schien nun wirksam zu sein.</p>
<p>Da gibt es einen Cache dachte ich mir. Und nach einiger Recherche im Internet stieß ich auf den folgenden interessanten Artikel von Junfeng Zang:<br />
<a href="http://blogs.msdn.com/b/junfeng/archive/2007/10/01/vista-activation-context-cache.aspx">Windows Vista Sxs Activation Context Cache</a></p>
<p>Wie man lesen kann, wird bei jedem erfolgreichen Einlesen einer Anwendung und dem erfolgreichen Laden aller Manifeste und DLLs, die ganzen ermittelten Daten in einen Cache gespeichert. Da ich die EXE aber nicht geändert habe, wurden auch die untergeordneten Manifeste nicht neu gelesen, auch wenn diese geändert wurden.</p>
<p>Durch das Ändern des Datums der EXE werden die Cacheeinträge ungültig, und danach werden alle Aktivierungskontexte der Anwednung und aller anderen Assemblies neu geladen.</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2011/04/25/auf-was-man-unbedingt-achten-muss-wenn-man-an-manifesten-fur-assemblies-herumbastelt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Umstellung eines Projektes auf VS-2010 schaltet DEP (/NXCOMPAT) ein und ASLR (/DYNAMICBASE) ein</title>
		<link>http://blog.m-ri.de/index.php/2011/03/26/umstellung-eines-projektes-auf-vs-2010-schaltet-dep-nxcompat-ein-und-aslr-dynamicbase-ein/</link>
		<comments>http://blog.m-ri.de/index.php/2011/03/26/umstellung-eines-projektes-auf-vs-2010-schaltet-dep-nxcompat-ein-und-aslr-dynamicbase-ein/#comments</comments>
		<pubDate>Sat, 26 Mar 2011 19:51:33 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Vista / Windows 7]]></category>
		<category><![CDATA[VS 2010]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[ASLR]]></category>
		<category><![CDATA[Crash]]></category>
		<category><![CDATA[Debuggen]]></category>
		<category><![CDATA[VS-2010]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=649</guid>
		<description><![CDATA[Bei der Umstellung eines Projektes von VS-2005 auf VS-2010 lief unsere Software im Testfeld ohne Probleme, bis auf einem Rechner, auf dem gezielt immer wieder der selbe Fehler auftrat. Der Stackdump zeigte aber immer wieder eine unterschiedliche Absturzadresse. Glücklicherweise konnten wir durch Crash-Dumps einigermaßen lokalisieren was passierte. Eigentümlicherweise zeigte sich der Crash immer beimAufruf einer [...]]]></description>
			<content:encoded><![CDATA[<p>Bei der Umstellung eines Projektes von <em>VS-2005</em> auf <em>VS-2010 </em>lief unsere Software im Testfeld ohne Probleme, bis auf einem Rechner, auf dem gezielt immer wieder der selbe Fehler auftrat.</p>
<p>Der Stackdump zeigte aber immer wieder eine unterschiedliche Absturzadresse. Glücklicherweise konnten wir durch Crash-Dumps einigermaßen lokalisieren was passierte. Eigentümlicherweise zeigte sich der Crash immer beimAufruf einer bestimmten Windows-Prozedur:</p>
<p><a href="http://blog.m-ri.de/wp-content/uploads/2010/07/DEP4.png"><img title="DEP4" src="http://blog.m-ri.de/wp-content/uploads/2010/07/DEP4.png" alt="" width="773" height="185" /></a></p>
<p>Eigentümlicherweise lief das selbe Programm mit <em>VS-2005 </em>kompiliert auf allen Maschinen. Also vermutete ich einen Compilerfehler! Aber wie kann ein Compilerfehler nur auf einer Maschine zu einem Problem werden?</p>
<p>Aber ich lag komplett daneben.<br />
Nach der Analyse des Codes stellte sich heraus das <em>DEP</em> die Ursache war, und das der Crash nur auf der einizgen Maschine auftrat, auf der <em>DEP</em> unterstützt wurde und eingeschaltet war.</p>
<p><a href="http://blog.m-ri.de/wp-content/uploads/2010/07/DEP1.png"><img title="DEP1" src="http://blog.m-ri.de/wp-content/uploads/2010/07/DEP1.png" alt="" width="380" height="542" /></a></p>
<p>Die anderen Rechner im Testfeld unterstützen <em>DEP</em> nicht:</p>
<p><a href="http://blog.m-ri.de/wp-content/uploads/2010/07/DEP2.png"><img class="alignnone size-full wp-image-752" title="DEP2" src="http://blog.m-ri.de/wp-content/uploads/2010/07/DEP2.png" alt="" width="384" height="548" /></a></p>
<p>Und auf diesen trat der Fehler nicht auf.</p>
<p>Weitere Analyse zeigte, dass ein spezieller Code aus einer Fensterklasse, die ich von einer Libary übernommen hatte ein spezielles Windows Subclassing mit einem Thunking ähnlich wie <em>ATL</em> machte, jedoch wurde der Speicher nicht korrekt als ausführbar markierte.<br />
Folgerichtig krachte es. D.h. die paar Codezeilen, die gerade mal einen JMP und das laden eines Registers durchführten wurden von <em>DEP</em> als illegal betrachtet und es kam zum Crash.</p>
<p>Und das eigentümliche, dass der Code mit <em>VS-2005</em> kompiliert lief, war auch schnell erklärt.<br />
Als das Projekt von <em>VS-2005 </em>in <em>VS-2010 </em>übernommen wurde, wurden auch die Optionen für <em>DEP</em> (<em>/NXCOMPAT</em>) und auch <em>ASLR</em> (<em>/DYNAMICBASE</em>) eingeschaltet <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_exclaim.gif' alt=':!:' class='wp-smiley' /> </p>
<p><a href="http://blog.m-ri.de/wp-content/uploads/2010/07/DEP3.png"><img class="alignnone size-full wp-image-753" title="DEP3" src="http://blog.m-ri.de/wp-content/uploads/2010/07/DEP3.png" alt="" width="853" height="291" /></a></p>
<p>Das ist eigentlich nicht nett, denn es hat schon einige weitreichende Konsequenzen für die Software.<br />
Also aufgepast bei der Konvertierung von Programmen und genau darüber nachgedacht ob man <em>DEP</em> und <em>ASLR</em> wirklich für seine Software will <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_exclaim.gif' alt=':!:' class='wp-smiley' /> </p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2011/03/26/umstellung-eines-projektes-auf-vs-2010-schaltet-dep-nxcompat-ein-und-aslr-dynamicbase-ein/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>C:\WINDOWS\TEMP und die Tücken von Programme der Kategorie &#8220;es war einmal&#8221;</title>
		<link>http://blog.m-ri.de/index.php/2011/01/21/cwindowstemp-und-die-tuecken-von-programme-der-kategorie-es-war-einmal/</link>
		<comments>http://blog.m-ri.de/index.php/2011/01/21/cwindowstemp-und-die-tuecken-von-programme-der-kategorie-es-war-einmal/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 19:05:30 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[Vista / Windows 7]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[Legacy]]></category>
		<category><![CDATA[Rechte]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=639</guid>
		<description><![CDATA[Es waren einmal die Zeiten in denen man in C:\WINDOWS\TEMP einfach mal eine Datei anlegen konnte und jeder darauf zugreifen konnte. Seit Windows Vista hat sich ja einiges getan was Sicherheit betrifft, besonders auch die Rechtevergabe auf Dateien, die im C:\Windows\Temp Ordner angelegt werden. Ein Programm  im Rentenalter (es ist gerade mal so um die 16 Jahre [...]]]></description>
			<content:encoded><![CDATA[<p>Es waren einmal die Zeiten in denen man in <em>C:\WINDOWS\TEMP</em> einfach mal eine Datei anlegen konnte und jeder darauf zugreifen konnte.<br />
Seit Windows Vista hat sich ja einiges getan was Sicherheit betrifft, besonders auch die Rechtevergabe auf Dateien, die im <em>C:\Windows\Temp </em>Ordner angelegt werden.</p>
<p>Ein Programm  im Rentenalter (es ist gerade mal so um die 16 Jahre alt <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  geschätzt) erzeugte in <em>C:\WINDOWS\TEMP </em>eine Datei, mit der bestimmte Zugriffe abgesichert wurden. Darunter auch wenn mehrere Instanzen des Programms auf einem Rechner liefen. Das funktionierte prima. Die Datei wurde unter einem festen Namen angelegt und nicht entfernt, nachdem das Programm beendet wurde.</p>
<p>Seit <em>Vista</em> gibt es aber nun ein kleines Problem.:<br />
Seit <em>Windows Vista </em>darf in <em>C:\WINDOWS\TEMP </em>immer noch jeder User Dateien erzeugen. Auf diese Dateien hat er auch vollen Zugriff. Aber auf diese Dateien hat kein anderer Nutzer mehr Zugriff&#8230; <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_surprised.gif' alt=':eek:' class='wp-smiley' />  &#8230; und selbst ein Admin muss erst hier erst den Besitz übernehmen, wenn er die Datei nicht erzeugt hat.</p>
<p>Und nun hat diese kleine alte Programm den folgenden Effekt:</p>
<ul>
<li>Benutzer A meldet sich an.</li>
<li>Benutzer A startet das Programm Er arbeitet damit und die temporäre Datei wird in <em>C:\WINDOWS\TEMP </em>angelegt.</li>
<li>Benutzer A meldet sich ab und beendet das Programm.</li>
<li>Benutzer B meldet sich an.</li>
<li>Benutzer B startet das Programm und &#8230; bekommt eine Fehlermeldung mit einem <strong>&#8220;Access denied!&#8221;</strong>.</li>
</ul>
<p>Mit den neuen Rechten, die auf dem <em>C:\WINDOWS\TEMP </em>Verzeichnis liegen, kann der zweite Benutzer auf diese Datei nicht mehr zugreifen auf die eben nur der Erzeuger Zugriff hat, und der ist eben Benutzer A.</p>
<p>PS: Es Frage mich keiner warum <em>C:\WINDOWS\TEMP </em>aus GetWindowsDir und angehängtem Text <em>TEMP </em>zusammengesetzt wurde. Vermutlich um zu umgehen, dass ein privates temporäres Verzeichnis benutzt wird. Tja und <em>CSIDL_APPDATA </em>war dem damaligen Entwickler (evtl. noch unter Windows 3.1) nicht bekannt.</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2011/01/21/cwindowstemp-und-die-tuecken-von-programme-der-kategorie-es-war-einmal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Warum es manchmal nicht genügt die Basisklasse aufzurufen und die miesen Konsequenzen&#8230;</title>
		<link>http://blog.m-ri.de/index.php/2010/12/04/warum-es-manchmal-nicht-genuegt-die-basisklasse-aufzurufen-und-die-miesen-konsequenzen/</link>
		<comments>http://blog.m-ri.de/index.php/2010/12/04/warum-es-manchmal-nicht-genuegt-die-basisklasse-aufzurufen-und-die-miesen-konsequenzen/#comments</comments>
		<pubDate>Sat, 04 Dec 2010 16:46:50 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[Win32]]></category>
		<category><![CDATA[WinAPI]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=678</guid>
		<description><![CDATA[Wenn man eine Windowsnachricht bearbeitet dann ruft man in den meisten Fällen die Funktion der Elternklasse auf. Was aber, wenn man die Nachricht nicht nur entgegennehmen will, sondern sie &#8220;verändert&#8221; an die Basisfunktion weitergeben will. Was dann? Kein Problem denkt man. Man ändert die Parameter eben und gibt diese neuen Werte an die Basisklasse weiter. [...]]]></description>
			<content:encoded><![CDATA[<p>Wenn man eine Windowsnachricht bearbeitet dann ruft man in den meisten Fällen die Funktion der Elternklasse auf. Was aber, wenn man die Nachricht nicht nur entgegennehmen will, sondern sie &#8220;verändert&#8221; an die Basisfunktion weitergeben will. Was dann?<br />
Kein Problem denkt man. Man ändert die Parameter eben und gibt diese neuen Werte an die Basisklasse weiter.</p>
<p>Nehmen wir mal als Beispiel ein Eingabe Control, das sich möglichst intelligent verhalten soll. D.h. in diesem Fall, wenn ein Datum eingegeben wird, dann sollte auch bei der Eingabe auf numerischen Ziffernbock, das Komma in einen Punkt gewandelt werden, oder bei englischem Datumsformat in einen Slash&#8230;</p>
<p>Na OK. Man überschreibt als <em>CMyWnd::OnChar</em>. Man prüft ob ein bestimmtes Zeichen ankommt und wenn es mir passt, dann ändere ich den Parameter und gebe diesen dann an die Basis Funktion weiter.</p>
<p>:Eeek: aber was ist das? Der Code hat keine Wirkung? Egal was wir an die Basisfunktion übergeben, es ändert sich nichts. Warum?</p>
<p>Die Antwort liegt in dem für mich etwas eigentümlichen Design der <em>MFC</em>. Alle <em>CWnd </em>Nachrichten Routinen rufen letzten Endes immer genau ein und die selbe Funktion auf: <em>CWnd::Default(); </em>Aber was macht <em>CWnd::Default</em>? Es nimmt die <em><strong>ursprünglichen </strong></em>Parameter, die Windows mal gesendet hat und übergibt die an die Window-Proc des Fensters. D.h. alle tollen Manipulationen an der <em>WM_CHAR </em>Nachricht sind weg in dem Moment in dem <em>CWnd::OnChar</em> aufgerufen wird.</p>
<p>Was also tun, wenn man nun aber wirklich die <em>WM_CHAR </em>Nachricht manipulieren will?<br />
Eigentlich nicht schwer. Man macht das Gleiche, dass eben auch <em>CWnd::Default </em>macht. Man ruft <em>DefWindowProc </em>mit den passenden <em>wParam </em>und <em>lParam </em>Werten auf.</p>
<p>Aber jetzt wird es dumm <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_exclaim.gif' alt=':!:' class='wp-smiley' />  Damit umgehen wir alle anderen geerbten Funktionalitäten des Controls. Ich habe keine Ahnung was die Entwickler der <em>MFC </em>in der Anfangszeit dazu getrieben hat immer <em>CWnd::Default </em>aufzurufen? War es Ihnen zu kompliziert wieder aus den Parametern <em>wParam </em>und <em>lParam </em>zusammen zu bauen?</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2010/12/04/warum-es-manchmal-nicht-genuegt-die-basisklasse-aufzurufen-und-die-miesen-konsequenzen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ComboBox DropDown Höhe wird nicht mehr durch die Ressourcen definiert</title>
		<link>http://blog.m-ri.de/index.php/2010/11/26/combobox-dropdown-hoehe-wird-nicht-mehr-durch-die-ressourcen-definiert/</link>
		<comments>http://blog.m-ri.de/index.php/2010/11/26/combobox-dropdown-hoehe-wird-nicht-mehr-durch-die-ressourcen-definiert/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 21:22:17 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[ComCtl32]]></category>
		<category><![CDATA[Manifest]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[Win32]]></category>
		<category><![CDATA[WinAPI]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=689</guid>
		<description><![CDATA[Vor Jahren habe ich für die microsoft.public.de.vc FAQ den folgenden Beitrag geschrieben: Warum klappt meine ComboBox im DropDown-Stil in einem Dialog nicht auf? Beim Erstellen einer ComboBox in einem Dialog Template muss auch die Größe mit angegeben werden, die die ComboBox haben soll, wenn Sie denn aufgeklappt wird. Dies kann auf zwei Methoden geschehen. Methode [...]]]></description>
			<content:encoded><![CDATA[<p>Vor Jahren habe ich für die microsoft.public.de.vc FAQ den folgenden Beitrag geschrieben:<br />
<a href="#Q16">Warum klappt meine ComboBox im DropDown-Stil in einem Dialog nicht auf?</a></p>
<p style="padding-left: 30px;">Beim Erstellen einer ComboBox in einem Dialog Template muss auch die Größe mit angegeben werden, die die ComboBox haben soll, wenn Sie denn aufgeklappt wird. Dies kann auf zwei Methoden geschehen.</p>
<p style="padding-left: 30px;">Methode 1: ComboBox aus der Werkzeugleiste einfach durch einen Mausklick einsetzen. Anschließend auf den &#8220;DropDown&#8221;-Schalter klicken und nun die gewünschte Größe einstellen.</p>
<p style="padding-left: 30px;">Methode 2: ComboBox durch Ziehen eines Rechteckes auf dem Dialog einsetzen. In diesem Fall wird die Größe gleich korrekt bestimmt. Nachträgliche Änderung der Größe erfolgt dann wieder durch anklicken des &#8220;DropDown&#8221;-Schalters.</p>
<p style="padding-left: 30px;">Anmerkung: Die Größe einer ComboBox mit dem Stil CBS_DROPDOWN und CBS_DROPDOWNLIST im NICHT aufgeklappten Zustand kann beim Erzeugen nicht verändert werden. Diese Größe bestimmt Windows automatisch. Die Größe die bei CreateWindow/CreateWindowEx angegeben wird ist immer die Größe des Control im aufgeklappten Zustand. Nachdem ein gültiger Windowshandle auf die ComboBox existiert kann mit CComboBox::SetItemHeight die Höhe der Items bzw. des Editfelds der ComboBox verändert werden.</p>
<p>Jetzt habe ich entdeckt, dass dieser Beitrag eigentlich überflüssig geworden ist, seit dem es <em>COMCTL32</em> in der Version 6.0 gibt.<br />
Wenn ein Manifest für die 6.0 Version der Common Controls vorhanden ist, dann bestimmt die <em>COMCTL32</em> DLL automatisch selbst anhand der Höhe des Monitors und der Position der ComboBox wie groß der DropDown-Bereich sein kann.</p>
<p>Aufgefallen ist mir das, als ich in einer RC-Datei sah, dass eine ComboBox mit der Höhe gerade einmal 20 DLUs angegeben wurde. Da in der RC Datei normalerweise immer nur die DropDown-Höhe eingetragen ist, fragte ich mich warum bisher niemandem aufgefallen war, dass diese ComboBox, nicht aufklappt. Ein kurzer Test, zeigte allerdings, dass alles normal war und die Box, den halben Monitor in der Höhe einnahm.<br />
Ein weiter Test mit und ohne Manifest zeigte mir dann schnell, dass sich das Standardverhalten von Comboboxen offensichtlich verändert hat.</p>
<p><strong>Nachtrag (07.01.2011):<br />
</strong>Nur die neuen Common Controls ab Vista und <em>Windows 7</em> verhalten sich wie oben beschrieben. <em>Windows XP </em>(einschließlich <em>SP3</em>) verhält sich noch gemäß der MSDN WinAPI Doku. D.h. die Höhe wird nicht automatisch angepasst. Man kann sich eben auf nichts verlassen.</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2010/11/26/combobox-dropdown-hoehe-wird-nicht-mehr-durch-die-ressourcen-definiert/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Erstaunen: CMemDC ist Bestandteil der MFC!</title>
		<link>http://blog.m-ri.de/index.php/2010/11/06/erstaunen-cmemdc-ist-bestandteil-der-mfc/</link>
		<comments>http://blog.m-ri.de/index.php/2010/11/06/erstaunen-cmemdc-ist-bestandteil-der-mfc/#comments</comments>
		<pubDate>Sat, 06 Nov 2010 19:32:19 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[VS 2010]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[GDI]]></category>
		<category><![CDATA[MFC-Next]]></category>
		<category><![CDATA[MFCNext]]></category>
		<category><![CDATA[VS-2010]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=690</guid>
		<description><![CDATA[Wer Double Buffering benötigt und die MFC nutzt, der kennt auch CMemDC. Vermutlich eine der meist genutzten und kopierten Klassen, die auf CodeProject und CodeGuru vorgestellt wurden. http://www.codeproject.com/KB/GDI/flickerfree.aspx http://www.codeguru.com/cpp/misc/misc/flickerfreedrawing/article.php/c389/Flicker-free-drawing-using-memory-DC.htm Ich habe meine Erweiterung hier im Blog vorgestellt und die liegt normalerweise in einem separaten Namespace, wie alle meine Tool-Klassen. Nicht schlecht staunte ich, als ich keinen [...]]]></description>
			<content:encoded><![CDATA[<p>Wer Double Buffering benötigt und die <em>MFC nutzt, </em>der kennt auch <em>CMemDC</em>. Vermutlich eine der meist genutzten und kopierten Klassen, die auf <em>CodeProject </em>und <em>CodeGuru </em>vorgestellt wurden.<br />
<a href="http://www.codeproject.com/KB/GDI/flickerfree.aspx">http://www.codeproject.com/KB/GDI/flickerfree.aspx</a><br />
<a href="http://www.codeguru.com/cpp/misc/misc/flickerfreedrawing/article.php/c389/Flicker-free-drawing-using-memory-DC.htm">http://www.codeguru.com/cpp/misc/misc/flickerfreedrawing/article.php/c389/Flicker-free-drawing-using-memory-DC.htm</a></p>
<p>Ich habe meine Erweiterung <a href="http://blog.m-ri.de/index.php/2008/12/14/der-etwas-bessere-cmemdc/">hier im Blog</a> vorgestellt und die liegt normalerweise in einem separaten Namespace, wie alle meine Tool-Klassen.</p>
<p>Nicht schlecht staunte ich, als ich keinen Compilerfehler bekam obwohl ich <em>CMemDC </em>nutzte aber keinen Namespace angab. Siehe da: <em>CMemDC </em>hat in einer eigenen Implementierung den Weg in die MFC gefunden. Man findet sie in:<br />
<em>C:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\include\afxcontrolbarutil.h</em></p>
<p>Im Großen und Ganzen ist es die bekannte Standard-Implementierung, allerdings verfügt diese <em>CMemDC </em>Version auch Code, der auf <em>Windows Vista </em>und <em>Windows 7</em>,<em> </em>die fest im Betriebssystem verankerten Funktionen nutzt: <em>BeginBufferedPaint</em>, <em>EndBufferedPaint</em><br />
Siehe <a href="http://msdn.microsoft.com/en-us/library/bb773178(VS.85).aspx">http://msdn.microsoft.com/en-us/library/bb773178(VS.85).aspx</a><br />
Diese Funktionen werden innerhalb des Themeings von <em>Windows Vista </em>und <em>Windows 7 </em>verwendet und in dieser Funktionsgruppe ist auch Alphablending direkt verankert. (<em>BufferedPaintSetAlpha</em>). Ich vermute sogar, dass diese integrierten Klassen effektiver arbeiten, als die eigenen Klassen (ein Test steht noch aus), denn Windows weiß intern natürlich viel besser was wie zu puffern und zu zeichnen ist, als wir, wenn <em>WM_PAINT </em>aufgerufen wird.</p>
<p>Vielleicht ein guter Grund, die eigene CMemDC Klasse auch auf Vista/Windows 7 Funktionen zu erweitern oder die integrierte Klasse in der MFC zu verwenden.</p>
<p>Tipp: Übrigens hat die <em>MFC CMemDC </em>Klasse einen statischen Member, der es auf einfache Weise erlaubt das Double-Buffering abzuschalten (<em>CMemDC:: m_bUseMemoryDC</em>), dass ist besonders interessant beim Debuggen von grafischen Operationen, deren Ergebnisse man auch gleich sehen will, allerdings wird dieser Member nicht benutzt wenn das interne <em>Windows Double-Buffering </em>genutzt werden kann, schade eigentlich.</p>
<p>PS: Aber eigentlich muss man sich auch die Frage stellen, warum die Entwickler genau diesen Klassennamen verwendet haben, denn er provoziert ja auch direkt den Konflikt mit existierendem Code.</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2010/11/06/erstaunen-cmemdc-ist-bestandteil-der-mfc/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Warum unter Vista und Windows 7 C:\Programme nicht genau dasselbe ist wie C:\Program Files</title>
		<link>http://blog.m-ri.de/index.php/2010/09/16/warum-unter-vista-und-windows-7-cprogramme-nicht-genau-das-selbe-ist-wie-cprogram-files/</link>
		<comments>http://blog.m-ri.de/index.php/2010/09/16/warum-unter-vista-und-windows-7-cprogramme-nicht-genau-das-selbe-ist-wie-cprogram-files/#comments</comments>
		<pubDate>Thu, 16 Sep 2010 19:03:30 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[Vista / Windows 7]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[WinAPI]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=651</guid>
		<description><![CDATA[Jeder kennt von Windows Vista und Windows 7 die Junctions &#8220;C:\Programme&#8221; oder &#8220;C:\Dokumente und Einstellungen&#8221;. Diese Verweise erlauben es auch älteren Programmen die evtl. hardcodierte Verzeichnisnamen haben oder auch Programmen, die die alten Verzeichnisstrukturen von Windows 2000 und XP nutzen korrekt zu arbeiten. Jetzt könnte man meinen, dass es vollkommen egal ist ob man nun [...]]]></description>
			<content:encoded><![CDATA[<p>Jeder kennt von <em>Windows Vista </em>und <em>Windows 7 </em>die <em>Junctions</em> <em>&#8220;C:\Programme&#8221;</em> oder <em>&#8220;C:\Dokumente und Einstellungen&#8221;</em>.<br />
Diese Verweise erlauben es auch älteren Programmen die evtl. hardcodierte Verzeichnisnamen haben oder auch Programmen, die die alten Verzeichnisstrukturen von <em>Windows 2000</em> und <em>XP</em> nutzen korrekt zu arbeiten.</p>
<p>Jetzt könnte man meinen, dass es vollkommen egal ist ob man nun <em>&#8220;C:\Programme&#8221;</em> oder <em>&#8220;C:\Program Files&#8221;</em> benutzt.<br />
Aber das ist es nicht <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_exclaim.gif' alt=':!:' class='wp-smiley' />  Es gibt ein paar ganz feine Unterschiede.</p>
<p>Ein simpler <em>DIR</em> auf der Befehlszeile</p>

<div class="wp_syntax"><div class="code"><pre class="cmd" style="font-family:monospace;">C:\&gt;dir C:\Programme
 Datenträger in Laufwerk C: ist C-LAPTOP
 Volumeseriennummer: D483-432C
&nbsp;
 Verzeichnis von C:\Programme
&nbsp;
Datei nicht gefunden</pre></div></div>

<p>macht das Problem offensichtlich!<br />
Und was geht hier ab?</p>
<p>Die Antwort liefert ICACLS für die Junction:</p>

<div class="wp_syntax"><div class="code"><pre class="cmd" style="font-family:monospace;">C:\&gt;icacls C:\Programme
C:\Programme Jeder:(DENY)(S,RD)
             Jeder:(RX)
             NT-AUTORITÄT\SYSTEM:(F)
             ORDEFINIERT\Administratoren:(F)</pre></div></div>

<p>Dagegen zeigt ICACLS für das Verzeichnis selbst</p>

<div class="wp_syntax"><div class="code"><pre class="cmd" style="font-family:monospace;">C:\&gt;icacls &quot;C:\Program Files&quot;
C:\Program Files NT SERVICE\TrustedInstaller:(F)
                 NT SERVICE\TrustedInstaller:(CI)(IO)(F)
                 NT-AUTORITÄT\SYSTEM:(M)
                 NT-AUTORITÄT\SYSTEM:(OI)(CI)(IO)(F)
                 VORDEFINIERT\Administratoren:(M)
                 VORDEFINIERT\Administratoren:(OI)(CI)(IO)(F)
                 VORDEFINIERT\Benutzer:(RX)
                 VORDEFINIERT\Benutzer:(OI)(CI)(IO)(GR,GE)
                 ERSTELLER-BESITZER:(OI)(CI)(IO)(F)</pre></div></div>

<p>Während man auf &#8220;C:\Program Files&#8221; die Rechte sieht, die man auch erwartet, liegt auf der Junction selbst eine Einschränkung:<br />
Die Berechtigung zum &#8220;Ordner Auflisten&#8221; wird verweigert für &#8220;Jeder&#8221; <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_exclaim.gif' alt=':!:' class='wp-smiley' /><br />
Jeder der neu eingeführten Junctions hat diese Einschränkung.</p>
<p>Meines Erachtens wurde dies gemacht um beim Durchsuchen von Verzeichnisstrukturen nicht unendliche Rekursionen zu erzeugen oder Verzeichnisse oder Dateien doppelt aufzuführen.<br />
Eine Verzeichnis Rekursion ergäbe sich zum Beispiel durch die Junction <em>Anwendungsdaten</em> im Verzeichnis <em>C:\Users\Username\AppData\Local</em>, der exakt wieder auf das Verzeichnis <em>C:\Users\Username\AppData\Local </em>verweist.</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2010/09/16/warum-unter-vista-und-windows-7-cprogramme-nicht-genau-das-selbe-ist-wie-cprogram-files/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bug: VC-2010 MFC CFormView zeichnet Buttons beim Rollen falsch, es erscheinen schwarze Blöcke</title>
		<link>http://blog.m-ri.de/index.php/2010/08/28/bug-vc-2010-cformview-zeichnet-buttons-beim-rollen-falsch-es-erscheinen-schwarze-bloecke/</link>
		<comments>http://blog.m-ri.de/index.php/2010/08/28/bug-vc-2010-cformview-zeichnet-buttons-beim-rollen-falsch-es-erscheinen-schwarze-bloecke/#comments</comments>
		<pubDate>Sat, 28 Aug 2010 09:36:27 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Vista / Windows 7]]></category>
		<category><![CDATA[VS 2010]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[MFC-Next]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[VS-2010]]></category>
		<category><![CDATA[Windows 7]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=662</guid>
		<description><![CDATA[In der MFC 10.0 hat sich ein Bug eingeschlichen, der sich unter Windows Vista und Windows 7  bemerkbar macht. Unter Windows XP tritt der Fehler nicht auf. Das Problem tritt in jedem Stil auf, der DWM verwendet. D.h. nicht wenn Windows klassisch ausgewählt wird. Wenn auf einen CFormView mehrere Buttons liegen und der CFormView gerollt [...]]]></description>
			<content:encoded><![CDATA[<p>In der <em>MFC 10.0 </em>hat sich ein Bug eingeschlichen, der sich unter <em>Windows Vista </em>und <em>Windows 7  </em>bemerkbar macht. Unter Windows XP tritt der Fehler nicht auf. Das Problem tritt in jedem Stil auf, der <em>DWM</em> verwendet. D.h. nicht wenn Windows klassisch ausgewählt wird.</p>
<p>Wenn auf einen <em>CFormView</em> mehrere Buttons liegen und der <em>CFormView</em> gerollt wird, dann kommt es unter Umständen zu Fehlern beim Neuzeichnen von Buttons. Dies schließt alle Button-Formen ein: <em>Check-Buttons</em>, <em>Radio-Buttons </em>und normale <em>Buttons</em>.</p>
<p>Das Ganze sieht nach dem Rollen in etwa so aus:<br />
<a href="http://blog.m-ri.de/wp-content/uploads/2010/08/CScrollView.png"><img class="alignnone size-full wp-image-663" title="CScrollView Bug" src="http://blog.m-ri.de/wp-content/uploads/2010/08/CScrollView.png" alt="" width="319" height="110" /></a></p>
<p>Der Text einiger Buttons erscheint nach dem Rollen als schwarze Blöcke. Es kann auch vorkommen, dass nur Teile der Buttons falsch gezeichnet werden.</p>
<p>Um das Problem gezielt nachzuvollziehen habe ich ein kleines Sample gebaut. Man kann durch zwei Schalter den CScrollView gezielt nach oben oder unten Rollen. Beim Rollen nach unten und bei bestimmten Fenstergrößen tritt dann der Fehler auf. Ich habe das Main-Window entsprechend beim Start in der Größe angepasst.</p>
<p>Das Problem liegt in einer Implementierung von <em>WM_PRINTCLIENT </em>in <em>CScrollView (CScrollView::OnPrintClient)</em>, die ein Double-Buffering verwendet, dass entweder falsch ist oder sich eben mit der Standardimplementierung eines Dialoges beißt. Auf den ersten und zweiten Blick konnte ich in der Implementierung selbst keinen Fehler sehen. Deshalb vermute ich, dass sich dieses Double-Buffering mit dem auch vorhandenen Double-Buffering in den Standardimplementierungen der Dialogklasse beißt bzw. nicht korrekt berücksichtigt, dass auch Child-Windows neu gezeichnet werden müssen.</p>
<p>Die Lösung ist entsprechend einfach:</p>
<ul>
<li>Man fügt einfach einen Handler für <em>WM_PRINTCLIENT </em>in seiner von <em>CFormView</em> abgeleiteten Klasse ein.</li>
<li>Dieser Handler ruft dann nicht die Implementierung der Basisklasse <em>CFormView</em> auf, sondern die Implementierung in <em>CView</em> (<em>CView::OnPrintClient</em>).</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">...
<span style="color: #007788;">ON_MESSAGE</span><span style="color: #008000;">&#40;</span>WM_PRINTCLIENT,<span style="color: #000040;">&amp;</span>CScrollDialogMFCView<span style="color: #008080;">::</span><span style="color: #007788;">OnPrintClient</span><span style="color: #008000;">&#41;</span>
...
&nbsp;
<span style="color: #007788;">LRESULT</span> CScrollDialogMFCView<span style="color: #008080;">::</span><span style="color: #007788;">OnPrintClient</span><span style="color: #008000;">&#40;</span> WPARAM wp, LPARAM lp <span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #666666;">// Bypass the CScrollView::OnPrintClient implementation</span>
  <span style="color: #0000ff;">return</span> CView<span style="color: #008080;">::</span><span style="color: #007788;">OnPrintClient</span><span style="color: #008000;">&#40;</span>wp,lp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Dieser Fehler ist in keiner der vorhergehenden MFC Versionen vorhanden (auch nicht in <em>MFCNext</em>), weil einfach kein entsprechender Handler vorhanden war..</p>
<p>Es stellt sich wohl bei einigen jetzt die Frage warum dieser Handler eingebaut wurde. Auch die Antwort ist einfach:<br />
Seit <em>Windows Vista</em> wird stark von <em>AnimateWindow</em> Gebrauch gemacht und auch <em>DWM</em> intern scheint des öfteren <em>WM_PRINT</em>/<em>WM_PRINTCLIENT</em> zu verwenden. Entsprechend haben fast alle Klassen in der <em>MFC</em> entsprechende Handler ergänzt bekommen.</p>
<p>Das Sample kann man hier herunterladen: <a href="http://blog.m-ri.de/wp-content/uploads/2010/08/ScrollDialogMFC-VS-2010.zip">ScrollDialogMFC &#8211; VS-2010</a>.<br />
Ich habe in der stdafx.h einen define <em>FIX_CSCROLLVIEW_PROBLEM</em> eingebaut mit dem man den Fix einfach aktivieren und deaktivieren kann.</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2010/08/28/bug-vc-2010-cformview-zeichnet-buttons-beim-rollen-falsch-es-erscheinen-schwarze-bloecke/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

