<?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>RemkoWeijnen.nl</title>
	<atom:link href="http://www.remkoweijnen.nl/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.remkoweijnen.nl/blog</link>
	<description>About Terminal Server, Citrix, Delphi and other stuff</description>
	<lastBuildDate>Mon, 05 Jul 2010 19:49:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Dear Visitor</title>
		<link>http://www.remkoweijnen.nl/blog/2007/11/01/dear-visitor/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=dear-visitor</link>
		<comments>http://www.remkoweijnen.nl/blog/2007/11/01/dear-visitor/#comments</comments>
		<pubDate>Thu, 01 Nov 2007 14:19:05 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.remkoweijnen.nl/blog/2007/11/01/dear-visitor/</guid>
		<description><![CDATA[Do you like my work? Did my work help you? Leave a comment and tell me how it was usefull to you. If you want you can make a donation with the Paypal Donate Button in the right Sidebar. Thank you! convert this post to pdf.]]></description>
			<content:encoded><![CDATA[<div class="announcement_post"><p>Do you like my work? Did my work help you?</p>
<ul>
<li>Leave a comment and tell me how it was usefull to you.</li>
<li>If you want you can make a donation with the Paypal Donate Button in the right Sidebar.</li>
</ul>
<p>Thank you!<br />
<!--p wp_dlm_show_downloads(3,$no);--></p>
 <span class="post2pdf_span" style="border: 1px solid gray; width: 160px; text-align: left; "><a href="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/generate.php?post=0" rel="nofollow"><img src="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/icon/pdf.png" width="16px" height="16px" />convert this post to pdf.</a></span></div>
]]></content:encoded>
			<wfw:commentRss>http://www.remkoweijnen.nl/blog/2007/11/01/dear-visitor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Detecting a Citrix Published Application</title>
		<link>http://www.remkoweijnen.nl/blog/2010/07/05/detecting-a-citrix-published-application/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=detecting-a-citrix-published-application</link>
		<comments>http://www.remkoweijnen.nl/blog/2010/07/05/detecting-a-citrix-published-application/#comments</comments>
		<pubDate>Mon, 05 Jul 2010 19:48:28 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[Citrix]]></category>

		<guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=615</guid>
		<description><![CDATA[While browsing through my old projects folder I found a little commandline tool that I wrote about a year ago. I needed to detect a certain published application on a Citrix environment in the loginscript. The tool detect the current Citrix published applicationname or if you are running Terminal Server aka Remote Desktop Services the [...]]]></description>
			<content:encoded><![CDATA[<p>While browsing through my old projects folder I found a little commandline tool that I wrote about a year ago. I needed to detect a certain published application on a Citrix environment in the loginscript.</p>
<p>The tool detect the current Citrix published applicationname or if you are running Terminal Server aka Remote Desktop Services the Initial Program name and stores this in an environment variable (APPNAME).</p>
<p>There are no parameters and there are no special dependancies (such as MFCom).</p>
<a class="downloadlink" href="http://www.remkoweijnen.nl/blog/download/CtxPubApp.zip" title="Version1.0 downloaded 16 times" >CtxPubApp (16)</a>
 <span class="post2pdf_span" style="border: 1px solid gray; width: 160px; text-align: left; "><a href="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/generate.php?post=g" rel="nofollow"><img src="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/icon/pdf.png" width="16px" height="16px" />convert this post to pdf.</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/07/05/detecting-a-citrix-published-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rating and contact options</title>
		<link>http://www.remkoweijnen.nl/blog/2010/06/29/rating-and-contact-options/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rating-and-contact-options</link>
		<comments>http://www.remkoweijnen.nl/blog/2010/06/29/rating-and-contact-options/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 11:49:09 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.remkoweijnen.nl/blog/2010/06/29/rating-and-contact-options/</guid>
		<description><![CDATA[I have installed a new rating plugin that gives you, my readers, a convenient and fast method to give feedback. So please do so, let me know what posts you find interesting! I have also added a Contact form in case you have any questions, article suggestions or maybe even consultation requests. The contact page [...]]]></description>
			<content:encoded><![CDATA[<p>I have installed a new rating plugin that gives you, my readers, a convenient and fast method to give feedback. So please do so, let me know what posts you find interesting!</p>
<p>I have also added a <a href="http://www.remkoweijnen.nl/blog/contact/">Contact</a> form in case you have any questions, article suggestions or maybe even consultation requests. The contact page is an attempt to streamline the e-mails I get from this blog so I hope this will work <img src='http://www.remkoweijnen.nl/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
 <span class="post2pdf_span" style="border: 1px solid gray; width: 160px; text-align: left; "><a href="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/generate.php?post=f" rel="nofollow"><img src="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/icon/pdf.png" width="16px" height="16px" />convert this post to pdf.</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/06/29/rating-and-contact-options/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun with asm</title>
		<link>http://www.remkoweijnen.nl/blog/2010/06/18/fun-with-asm/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=fun-with-asm</link>
		<comments>http://www.remkoweijnen.nl/blog/2010/06/18/fun-with-asm/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 10:02:00 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=604</guid>
		<description><![CDATA[Today just some fun stuff with ASM, probably not the most recommended way to do things but for sure the most geeky way Get the Current Session Id: function GetCurrentSessionId: DWORD; asm &#160; mov &#160; &#160; eax,fs:&#91;$00000018&#93;; &#160; // Get TEB &#160; mov &#160; &#160; eax,&#91;eax+$30&#93;; &#160; &#160; &#160; &#160;// PPEB &#160; mov &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Today just some fun stuff with ASM, probably not the most recommended way to do things but for sure the most geeky way <img src='http://www.remkoweijnen.nl/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Get the Current Session Id:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">function</span> GetCurrentSessionId: <span class="kw4">DWORD</span>;<br />
<span class="kw1">asm</span><br />
&nbsp; mov &nbsp; &nbsp; eax,fs:<span class="br0">&#91;</span><span class="re0">$<span class="nu0">00000018</span></span><span class="br0">&#93;</span>; &nbsp; <span class="co1">// Get TEB</span><br />
&nbsp; mov &nbsp; &nbsp; eax,<span class="br0">&#91;</span>eax+<span class="re0">$<span class="nu0">30</span></span><span class="br0">&#93;</span>; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">// PPEB</span><br />
&nbsp; mov &nbsp; &nbsp; eax,<span class="br0">&#91;</span>eax+<span class="re0">$1d4</span><span class="br0">&#93;</span>; &nbsp; &nbsp; &nbsp; <span class="co1">// PEB.SessionId</span><br />
<span class="kw1">end</span>;<br />
&nbsp;</div>
<p>Get the Current Console Session Id:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">function</span> GetConsoleSessionId: <span class="kw4">DWORD</span>;<br />
<span class="kw1">asm</span><br />
&nbsp; mov eax, <span class="br0">&#91;</span><span class="re0">$7ffe02d8</span><span class="br0">&#93;</span>;<br />
<span class="kw1">end</span>;</div>
<p>And&#8230; if we can read it we can also write it?</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">procedure</span> SetCurrentSessionId<span class="br0">&#40;</span><span class="kw1">const</span> SessionId: <span class="kw4">DWORD</span><span class="br0">&#41;</span>;<br />
<span class="kw1">asm</span><br />
&nbsp; mov &nbsp; &nbsp; edx,fs:<span class="br0">&#91;</span><span class="re0">$<span class="nu0">00000018</span></span><span class="br0">&#93;</span>;<br />
&nbsp; mov &nbsp; &nbsp; edx,<span class="br0">&#91;</span>edx+<span class="re0">$<span class="nu0">30</span></span><span class="br0">&#93;</span>;<br />
&nbsp; mov &nbsp; &nbsp; <span class="br0">&#91;</span>edx+<span class="re0">$1d4</span><span class="br0">&#93;</span>, SessionId;<br />
<span class="kw1">end</span>;</div>
<p>and</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">procedure</span> SetConsoleSessionId<span class="br0">&#40;</span><span class="kw1">const</span> SessionId: <span class="kw4">DWORD</span><span class="br0">&#41;</span>;<br />
<span class="kw1">var</span><br />
&nbsp; p: <span class="kw4">PDWORD</span>;<br />
&nbsp; OldProtect: <span class="kw4">DWORD</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; p := <span class="kw4">PDWORD</span><span class="br0">&#40;</span><span class="re0">$7ffe02d8</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw3">Win32Check</span><span class="br0">&#40;</span>VirtualProtect<span class="br0">&#40;</span>p, <span class="kw3">SizeOf</span><span class="br0">&#40;</span>p<span class="br0">&#41;</span>, PAGE_READWRITE, @OldProtect<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; p^ := SessionId;<br />
&nbsp; <span class="kw3">Win32Check</span><span class="br0">&#40;</span>VirtualProtect<span class="br0">&#40;</span>p, <span class="kw3">SizeOf</span><span class="br0">&#40;</span>p<span class="br0">&#41;</span>, OldProtect, @OldProtect<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</div>
<p>You can safely try it since it of course affects the current process only, so don&#8217;t worry.</p>
<p>And perhaps more usefull</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">procedure</span> SetIsDebuggerPresent<span class="br0">&#40;</span><span class="kw1">const</span> Value: <span class="kw4">Boolean</span><span class="br0">&#41;</span>;<br />
<span class="kw1">asm</span><br />
&nbsp; mov edx,fs:<span class="br0">&#91;</span><span class="re0">$<span class="nu0">00000018</span></span><span class="br0">&#93;</span>; &nbsp; &nbsp; <span class="co1">// TEB</span><br />
&nbsp; mov edx, <span class="br0">&#91;</span>edx+<span class="re0">$<span class="nu0">30</span></span><span class="br0">&#93;</span>; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// PPEB</span><br />
&nbsp; mov <span class="kw4">byte</span> <span class="kw3">ptr</span><span class="br0">&#91;</span>edx<span class="nu0">+2</span><span class="br0">&#93;</span>, Value; <span class="co1">// +0&#215;002 BeingDebugged &nbsp; &nbsp;: UChar</span><br />
<span class="kw1">end</span>;<br />
&nbsp;</div>
 <span class="post2pdf_span" style="border: 1px solid gray; width: 160px; text-align: left; "><a href="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/generate.php?post=\" rel="nofollow"><img src="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/icon/pdf.png" width="16px" height="16px" />convert this post to pdf.</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/06/18/fun-with-asm/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Obtain Fully Qualified Domain Name from Netbios Domain Name</title>
		<link>http://www.remkoweijnen.nl/blog/2010/06/17/obtain-fully-qualified-domain-name-from-netbios-domain-name/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=obtain-fully-qualified-domain-name-from-netbios-domain-name</link>
		<comments>http://www.remkoweijnen.nl/blog/2010/06/17/obtain-fully-qualified-domain-name-from-netbios-domain-name/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 12:34:42 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=601</guid>
		<description><![CDATA[I needed to obtain the Fully Qualified Domain Name (FQDN) for a given NetBios domain name. Eg from MYDOMAIN to dc=mydomain,dc=local. I did some tests with the TranslateName API and if you append a \ to the domain name it returns the FQDN. Here is a short example: var &#160; Buffer: array&#91;0..MAX_PATH&#93; of Char; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>I needed to obtain the Fully Qualified Domain Name (FQDN) for a given NetBios domain name. Eg from MYDOMAIN to dc=mydomain,dc=local.</p>
<p>I did some tests with the <a href="http://msdn.microsoft.com/en-us/library/ms725484%28VS.85%29.aspx" target="_blank">TranslateName</a> API and if you append a \ to the domain name it returns the FQDN.</p>
<p>Here is a short example:</p>
<p><span id="more-601"></span></p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">var</span><br />
&nbsp; Buffer: <span class="kw1">array</span><span class="br0">&#91;</span><span class="nu0">0</span>..<span class="me1">MAX_PATH</span><span class="br0">&#93;</span> <span class="kw1">of</span> <span class="kw4">Char</span>;<br />
&nbsp; nSize: <span class="kw4">DWORD</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; nSize := <span class="kw3">Length</span><span class="br0">&#40;</span>Buffer<span class="br0">&#41;</span>;<br />
&nbsp; ZeroMemory<span class="br0">&#40;</span>@Buffer, <span class="kw3">SizeOf</span><span class="br0">&#40;</span>Buffer<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw3">Win32Check</span><span class="br0">&#40;</span>TranslateName<span class="br0">&#40;</span><span class="st0">&#8216;MYDOMAIN\&#8217;</span><span class="br0">&#41;</span>, NameSamCompatible, NameFullyQualifiedDN, Buffer, nSize<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="kw1">end</span>;</div>
 <span class="post2pdf_span" style="border: 1px solid gray; width: 160px; text-align: left; "><a href="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/generate.php?post=Y" rel="nofollow"><img src="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/icon/pdf.png" width="16px" height="16px" />convert this post to pdf.</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/06/17/obtain-fully-qualified-domain-name-from-netbios-domain-name/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Having fun with Windows Licensing</title>
		<link>http://www.remkoweijnen.nl/blog/2010/06/15/having-fun-with-windows-licensing/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=having-fun-with-windows-licensing</link>
		<comments>http://www.remkoweijnen.nl/blog/2010/06/15/having-fun-with-windows-licensing/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 13:09:14 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[Windows 7]]></category>

		<guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=588</guid>
		<description><![CDATA[If you look into the registry in the key HKLM\System\CurrentControlSet\ProductOptions you will find several licensing related Values. The ProductType and ProductSuite keys contain the OS Suite and Edition, but the ProductPolicy key is much more interesting. So let&#8217;s have a closer look at it, open RegEdit and DoubleClick the key, you will something like the [...]]]></description>
			<content:encoded><![CDATA[<p>If you look into the registry in the key HKLM\System\CurrentControlSet\ProductOptions you will find several licensing related Values.</p>
<p>The ProductType and ProductSuite keys contain the OS Suite and Edition, but the ProductPolicy key is much more interesting. So let&#8217;s have a closer look at it, open RegEdit and DoubleClick the key, you will something like the screenshot below, a Binary Value:</p>
<p><a href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/06/productpolicy1-1.png" rel="lightbox[588]"><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/06/productpolicy1-1-small.png" alt="ProductPolicy1" width="215" height="188" /></a></p>
<p>As you can see the license names are there as a Unicode string and later on I will show you how we can read the values. But because I didn&#8217;t want to extract all the names manually I decided to see if I could reverse the used structure because it didn&#8217;t look very complicated. Using a Hex Editor I could determine the important part of the structure.</p>
<p><span id="more-588"></span>It starts with a header:</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp;TProductPolicyHeader = <span class="kw1">packed</span> <span class="kw1">record</span><br />
&nbsp; &nbsp; cbSize: <span class="kw4">DWORD</span>;<br />
&nbsp; &nbsp; cbDataSize: <span class="kw4">DWORD</span>;<br />
&nbsp; &nbsp; cbEndMarker: <span class="kw4">DWORD</span>;<br />
&nbsp; &nbsp; Unknown1: <span class="kw4">DWORD</span>;<br />
&nbsp; &nbsp; Unknown2: <span class="kw4">DWORD</span>;<br />
&nbsp; <span class="kw1">end</span>;</div>
<p>then an array of values follows:</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp;TProductPolicyValue = <span class="kw1">packed</span> <span class="kw1">record</span><br />
&nbsp; &nbsp; cbSize: <span class="kw4">Word</span>;<br />
&nbsp; &nbsp; cbName: <span class="kw4">Word</span>;<br />
&nbsp; &nbsp; SlDatatype: <span class="kw4">Word</span>;<br />
&nbsp; &nbsp; cbData: <span class="kw4">Word</span>;<br />
&nbsp; &nbsp; Unknown1: <span class="kw4">DWORD</span>;<br />
&nbsp; &nbsp; Unknown2: <span class="kw4">DWORD</span>;<br />
&nbsp; <span class="kw1">end</span>;</div>
<p>The SlDataType is a word value that corresponds to the values of the SLDATATYPE enum:</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp;_tagSLDATATYPE =<br />
&nbsp; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; SL_DATA_NONE &nbsp; &nbsp; &nbsp; = REG_NONE,<br />
&nbsp; &nbsp; SL_DATA_SZ &nbsp; &nbsp; &nbsp; &nbsp; = REG_SZ,<br />
&nbsp; &nbsp; SL_DATA_DWORD &nbsp; &nbsp; &nbsp;= REG_DWORD,<br />
&nbsp; &nbsp; SL_DATA_BINARY &nbsp; &nbsp; = REG_BINARY,<br />
&nbsp; &nbsp; SL_DATA_MULTI_SZ &nbsp; = REG_MULTI_SZ,<br />
&nbsp; &nbsp; SL_DATA_SUM &nbsp; &nbsp; &nbsp; &nbsp;= <span class="nu0">100</span><br />
&nbsp; <span class="br0">&#41;</span>;<br />
&nbsp; SLDATATYPE = _tagSLDATATYPE;<br />
&nbsp; TSlDataType = SLDATATYPE;<br />
&nbsp; PSlDataType = ^SLDATATYPE;</div>
<p>And we end with an End Marker (of size cbEndMarker).</p>
<p>Then I wrote some code to parse the structure:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">procedure</span> TForm1.<span class="me1">ParseProductPolicy</span>;<br />
<span class="kw1">const</span><br />
&nbsp; KeyName = <span class="st0">&#8216;SYSTEM\CurrentControlSet\Control\ProductOptions&#8217;</span>;<br />
&nbsp; ValueName = <span class="st0">&#8216;ProductPolicy&#8217;</span>;<br />
<span class="kw1">var</span><br />
&nbsp; HourGlass: IHourGlass;<br />
&nbsp; ms: TMemoryStream;<br />
&nbsp; Reg: TRegistry;<br />
&nbsp; CurPos: <span class="kw4">Int64</span>;<br />
&nbsp; Header: TProductPolicyHeader;<br />
&nbsp; Value: TProductPolicyValue;<br />
&nbsp; Name: UnicodeString;<br />
<span class="kw1">begin</span><br />
&nbsp; HourGlass := TIHourGlass.<span class="me1">Create</span>;<br />
&nbsp; ms := TMemoryStream.<span class="me1">Create</span>;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; ListView1.<span class="me1">Items</span>.<span class="me1">BeginUpdate</span>;<br />
&nbsp; &nbsp; Reg := TRegistry.<span class="me1">Create</span>;<br />
&nbsp; &nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; &nbsp; Reg.<span class="me1">RootKey</span> := HKEY_LOCAL_MACHINE;<br />
&nbsp; &nbsp; &nbsp; <span class="coMULTI">{ &nbsp;Open &nbsp;ProductOptions Key }</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> Reg.<span class="me1">OpenKeyReadOnly</span><span class="br0">&#40;</span>KeyName<span class="br0">&#41;</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">begin</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">{ Get ProductPolicy Size }</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ms.<span class="me1">Size</span> := Reg.<span class="me1">GetDataSize</span><span class="br0">&#40;</span>ValueName<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ms.<span class="me1">Size</span> &gt; <span class="nu0">0</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">begin</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">{ Read ProductPolicy Data into MemoryStream }</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Reg.<span class="me1">ReadBinaryData</span><span class="br0">&#40;</span>ValueName, ms.<span class="me1">Memory</span>^, ms.<span class="me1">Size</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">end</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span>;<br />
&nbsp; &nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; &nbsp; Reg.<span class="me1">Free</span>;<br />
&nbsp; &nbsp; <span class="kw1">end</span>;</p>
<p>&nbsp; &nbsp; <span class="coMULTI">{ Read Header }</span><br />
&nbsp; &nbsp; ms.<span class="me1">ReadBuffer</span><span class="br0">&#40;</span>Header, <span class="kw3">SizeOf</span><span class="br0">&#40;</span>Header<span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="coMULTI">{ Loop through the Values }</span><br />
&nbsp; &nbsp; <span class="kw1">while</span> ms.<span class="me1">Size</span> &#8211; Header.<span class="me1">cbEndMarker</span> &gt; ms.<span class="me1">Position</span> <span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="kw1">begin</span><br />
&nbsp; &nbsp; &nbsp; <span class="coMULTI">{ Store current position }</span><br />
&nbsp; &nbsp; &nbsp; CurPos := ms.<span class="me1">Position</span>;</p>
<p>&nbsp; &nbsp; &nbsp; <span class="coMULTI">{ Read Value }</span><br />
&nbsp; &nbsp; &nbsp; ms.<span class="me1">ReadBuffer</span><span class="br0">&#40;</span>Value, <span class="kw3">SizeOf</span><span class="br0">&#40;</span>Value<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="coMULTI">{ Set Name length }</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">SetLength</span><span class="br0">&#40;</span>Name, Value.<span class="me1">cbName</span> <span class="kw1">div</span> <span class="kw3">SizeOf</span><span class="br0">&#40;</span>WChar<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="coMULTI">{ Read Name }</span><br />
&nbsp; &nbsp; &nbsp; ms.<span class="me1">ReadBuffer</span><span class="br0">&#40;</span>Name<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, Value.<span class="me1">cbName</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; <span class="coMULTI">{ Read License Value }</span><br />
&nbsp; &nbsp; &nbsp; CheckValue<span class="br0">&#40;</span>Name<span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; <span class="coMULTI">{ Jump to next Value }</span><br />
&nbsp; &nbsp; &nbsp; ms.<span class="kw3">Seek</span><span class="br0">&#40;</span>CurPos + Value.<span class="me1">cbSize</span>, soFromBeginning<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">end</span>;</p>
<p>&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; ListView1.<span class="me1">Items</span>.<span class="me1">EndUpdate</span>;<br />
&nbsp; &nbsp; ms.<span class="me1">Free</span>;<br />
&nbsp; <span class="kw1">end</span>;</p>
<p><span class="kw1">end</span>;</div>
<p>The procedure that reads the actual value is CheckValue, it uses the <a href="http://msdn.microsoft.com/en-us/library/aa965834%28VS.85%29.aspx" target="_blank">SLGetWindowsInformation</a> function:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">function</span> SLGetWindowsInformation<span class="br0">&#40;</span>pwszValueName: <span class="kw4">PWideChar</span>;<br />
&nbsp; <span class="kw1">var</span> peDataType: SLDATATYPE; <span class="kw1">var</span> pcbValue: UINT; <span class="kw1">var</span> ppbValue: <span class="kw4">PByte</span><span class="br0">&#41;</span>: HRESULT;<br />
&nbsp; <span class="kw1">stdcall</span>; external <span class="st0">&#8216;slc.dll&#8217;</span>;</div>
<p>The results are very interesting, I didn&#8217;t know there were so many licensable features in Windows!</p>
<p>You can check your results with the demo project (source included).<br />
<a class="downloadlink" href="http://www.remkoweijnen.nl/blog/download/LicenseDemo.rar" title="Version1.0 downloaded 41 times" >License Demo (41)</a></p>
<p>Here are the results from my Windows 7 Laptop:<br />
<a href="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/06/licensevalues.png" rel="lightbox[588]"><img src="http://www.remkoweijnen.nl/blog/wp-content/uploads/2010/06/licensevalues-small.png" alt="LicenseValues" width="430" height="1809" align="left" /></a></p>
 <span class="post2pdf_span" style="border: 1px solid gray; width: 160px; text-align: left; "><a href="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/generate.php?post=L" rel="nofollow"><img src="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/icon/pdf.png" width="16px" height="16px" />convert this post to pdf.</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/06/15/having-fun-with-windows-licensing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Memory Leaks when using the Virtual TreeView Component</title>
		<link>http://www.remkoweijnen.nl/blog/2010/06/09/memory-leaks-when-using-virtual-treeview-component/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=memory-leaks-when-using-virtual-treeview-component</link>
		<comments>http://www.remkoweijnen.nl/blog/2010/06/09/memory-leaks-when-using-virtual-treeview-component/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 07:50:49 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=577</guid>
		<description><![CDATA[Again a about post about using the Virtual TreeView component (did I mention it&#8217;s brilliant?), this time I will talk about memory leaks. I often use Records to hold the treedata, and usually the record holds some string data (eg a caption) and an (a reference to) an Interface or Object(List) that holds more data. [...]]]></description>
			<content:encoded><![CDATA[<p>Again a about post about using the <a href="http://www.soft-gems.net/index.php?option=com_content&amp;task=view&amp;id=12&amp;Itemid=33" target="_blank">Virtual TreeView component</a> (did I mention it&#8217;s brilliant?), this time I will talk about memory leaks.</p>
<p>I often use Records to hold the treedata, and usually the record holds some string data (eg a caption) and an (a reference to) an Interface or Object(List) that holds more data.</p>
<p>If you are familiar with Virtual Tree then you know that you must can the NodeData in the OnFreeNode event.</p>
<p><span id="more-577"></span>Let&#8217;s look at an example:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">type</span><br />
&nbsp; TTreeData = <span class="kw1">record</span><br />
&nbsp; &nbsp; Caption: <span class="kw4">String</span>;<br />
&nbsp; &nbsp; SessionList: ISessionList;<br />
&nbsp; &nbsp; Link: INode;<br />
&nbsp; <span class="kw1">end</span>;<br />
&nbsp; PTreeData = ^TTreeData;</div>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">procedure</span> TMainForm.<span class="me1">TreeViewFreeNode</span><span class="br0">&#40;</span>Sender: TBaseVirtualTree;<br />
&nbsp; Node: PVirtualNode<span class="br0">&#41;</span>;<br />
<span class="kw1">var</span><br />
&nbsp; TreeData: PTreeData;<br />
<span class="kw1">begin</span><br />
&nbsp; TreeData := Sender.<span class="me1">GetNodeData</span><span class="br0">&#40;</span>Node<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw3">Finalize</span><span class="br0">&#40;</span>TreeData^<span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</div>
<p>Looks allright doesn&#8217;t it? And still if you test for memoryleaks with Eurekalog or FastMM you will sometimes notice some leaks.</p>
<p>This happens because Virtual Treeview only calls the OnNodeFree event for Validated Nodes and a node that was never &#8220;touched&#8221; (eg the node was never visible and thus the GetText event was never called) was never validated.</p>
<p>In these cases you can manually validate the node when adding it</p>
<div class="dean_ch" style="white-space: wrap;">TreeView.<span class="me1">ValidateNode</span><span class="br0">&#40;</span>Child, <span class="kw2">False</span><span class="br0">&#41;</span>;</div>
 <span class="post2pdf_span" style="border: 1px solid gray; width: 160px; text-align: left; "><a href="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/generate.php?post=A" rel="nofollow"><img src="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/icon/pdf.png" width="16px" height="16px" />convert this post to pdf.</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/06/09/memory-leaks-when-using-virtual-treeview-component/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Setting ChildCount in a Virtual Tree</title>
		<link>http://www.remkoweijnen.nl/blog/2010/06/08/setting-childcount-in-a-virtual-tree/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=setting-childcount-in-a-virtual-tree</link>
		<comments>http://www.remkoweijnen.nl/blog/2010/06/08/setting-childcount-in-a-virtual-tree/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 15:39:57 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=573</guid>
		<description><![CDATA[When working with the Virtual TreeView component the most optimized way of adding (or removing child nodes is by changing the ChildCount. I often make the mistake of change the ChildCount of a Node using: Node^.ChildCount := Count; If you look into the source you will see why this will not work, the proper way [...]]]></description>
			<content:encoded><![CDATA[<p>When working with the <a href="http://www.soft-gems.net/index.php?option=com_content&amp;task=view&amp;id=12&amp;Itemid=33" target="_blank">Virtual TreeView component</a> the most optimized way of adding (or removing child nodes is by changing the ChildCount.</p>
<p>I often make the mistake of change the ChildCount of a Node using:</p>
<div class="dean_ch" style="white-space: wrap;">Node^.<span class="me1">ChildCount</span> := Count;</div>
<p>If you look into the source you will see why this will not work, the proper way is:</p>
<div class="dean_ch" style="white-space: wrap;">VirtualTree.<span class="me1">ChildCount</span><span class="br0">&#91;</span>Node<span class="br0">&#93;</span> := Count;</div>
<p>This is mainly a note to self since I tend to forget it all the time <img src='http://www.remkoweijnen.nl/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
 <span class="post2pdf_span" style="border: 1px solid gray; width: 160px; text-align: left; "><a href="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/generate.php?post==" rel="nofollow"><img src="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/icon/pdf.png" width="16px" height="16px" />convert this post to pdf.</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/06/08/setting-childcount-in-a-virtual-tree/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Random Active Directory Notes #4</title>
		<link>http://www.remkoweijnen.nl/blog/2010/03/30/random-active-directory-notes-4/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=random-active-directory-notes-4</link>
		<comments>http://www.remkoweijnen.nl/blog/2010/03/30/random-active-directory-notes-4/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 13:04:51 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=567</guid>
		<description><![CDATA[Previously I discussed IDirectoryObject, today I will show how to change a user&#8217;s password with IDirectoryObject. I didn&#8217;t find any documentation except a kb article describing how to use pure ldap to do it. Of course I could have used IADsUser::SetPassword but I decided not to because of the following reasons: IADs interfaces are terribly [...]]]></description>
			<content:encoded><![CDATA[<p>Previously I discussed IDirectoryObject, today I will show how to change a user&#8217;s password with IDirectoryObject.</p>
<p>I didn&#8217;t find any documentation except a <a href="http://support.microsoft.com/kb/269190" target="_self">kb article</a> describing how to use pure ldap to do it. Of course I could have used IADsUser::SetPassword but I decided not to because of the following reasons:</p>
<ul>
<li>IADs interfaces are terribly slow (although for one use you probably wouldn&#8217;t really notice).</li>
<li>IADsUser::SetPassword tries 3 different methods to set the password (ldap over ssl, kerberos and finally NetUserSetInfo) which makes it even slower (most domain controllers do not have an ssl certificate) and unpredictable.</li>
</ul>
<p>All example code I found was .NET based using the .NET wrappers for Active Directory and seemed to be meant for use in Adam rather than full Active Directory (it set port number to 389 and password mode to cleartext).</p>
<p>In the end it&#8217;s not very difficult but nonetheless it took me a while before I got it right.</p>
<p>We can write to the unicodePwd attribute which wants the password as a double quoted unicode string. If you look at this attribute with AdsiEdit you&#8217;ll see that the type is Octet String and that it can be written only.</p>
<p>I was tricked with Delphi&#8217;s QuotedStr function for a while because it doesn&#8217;t return a double but single quoted string <img src='http://www.remkoweijnen.nl/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Below a small snippet from the upcoming JwsclActiveDirectory that shows how to use it:<span id="more-567"></span></p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">procedure</span> TJwAdUser.<span class="me1">SetPassword</span><span class="br0">&#40;</span><span class="kw1">const</span> Value: TJwString<span class="br0">&#41;</span>;<br />
<span class="kw1">var</span><br />
&nbsp; AdValue: ADSVALUE;<br />
&nbsp; AdAttrInfo: ADS_ATTR_INFO;<br />
&nbsp; TempPwd: TJwString;<br />
&nbsp; DirObjIntf: IDirectoryObject;<br />
&nbsp; Count: <span class="kw4">DWORD</span>;<br />
&nbsp; hr: HRESULT;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="coMULTI">{ To set the password we need a secure bind to the Domain Controller, this<br />
&nbsp; &nbsp; is possible from win2000 sp5 and higher }</span><br />
&nbsp; hr := ADsOpenObject<span class="br0">&#40;</span><span class="kw4">PWideChar</span><span class="br0">&#40;</span>FPathName<span class="br0">&#41;</span>, <span class="kw2">nil</span>, <span class="kw2">nil</span>, ADS_USE_SIGNING<br />
&nbsp; &nbsp; <span class="kw1">or</span> ADS_USE_SEALING <span class="kw1">or</span> ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject,<br />
&nbsp; &nbsp; <span class="kw4">Pointer</span><span class="br0">&#40;</span>DirObjIntf<span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; <span class="kw1">if</span> failed<span class="br0">&#40;</span>hr<span class="br0">&#41;</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw1">raise</span> EJwsclAdNoInterfaceException.<span class="me1">CreateFmtEx</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span class="st0">&#8216;Interface %s not obtained&#8217;</span>, <span class="st0">&#8216;SetPassword&#8217;</span>, ClassName,<br />
&nbsp; &nbsp; &nbsp; <span class="st0">&#8216;JwsclActiveDirectory&#8217;</span>, <span class="nu0">0</span>, hr, <span class="br0">&#91;</span><span class="st0">&#8216;IID_IDirectoryObject&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; <span class="coMULTI">{ we can set the password through the unicodePwd attribute. }</span><br />
&nbsp; AdAttrInfo.<span class="me1">pszAttrName</span> := <span class="st0">&#8216;unicodePwd&#8217;</span>;<br />
&nbsp; AdAttrInfo.<span class="me1">dwControlCode</span> := ADS_ATTR_UPDATE;<br />
&nbsp; AdAttrInfo.<span class="me1">pADsValues</span> := @AdValue;<br />
&nbsp; AdAttrInfo.<span class="me1">dwNumValues</span> := <span class="nu0">1</span>;</p>
<p>&nbsp; <span class="coMULTI">{ the password needs to be within a double quoted string }</span><br />
&nbsp; TempPwd := <span class="kw3">AnsiQuotedStr</span><span class="br0">&#40;</span>Value, <span class="st0">&#8216;&quot;&#8217;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; <span class="coMULTI">{ unicodePwd is of type Octet String }</span><br />
&nbsp; AdValue.<span class="me1">dwType</span> := ADSTYPE_OCTET_STRING;<br />
&nbsp; AdValue.<span class="me1">OctetString</span>.<span class="me1">dwLength</span> := <span class="kw3">Length</span><span class="br0">&#40;</span>TempPwd<span class="br0">&#41;</span> * <span class="kw3">sizeof</span><span class="br0">&#40;</span>TempPwd<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; AdValue.<span class="me1">OctetString</span>.<span class="me1">lpValue</span> := @TempPwd<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>;</p>
<p>&nbsp; <span class="coMULTI">{ set the password }</span><br />
&nbsp; hr := DirObjIntf.<span class="me1">SetObjectAttributes</span><span class="br0">&#40;</span>@AdAttrInfo, <span class="nu0">1</span>, Count<span class="br0">&#41;</span>;</p>
<p>&nbsp; <span class="coMULTI">{ don&#8217;t keep the password in memory&#8230; }</span><br />
&nbsp; SecureZeroMemory<span class="br0">&#40;</span>@TempPwd<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, <span class="kw3">Length</span><span class="br0">&#40;</span>TempPwd<span class="br0">&#41;</span> * <span class="kw3">sizeof</span><span class="br0">&#40;</span>TempPwd<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; DirObjIntf := <span class="kw2">nil</span>;</p>
<p>&nbsp; <span class="kw1">if</span> failed<span class="br0">&#40;</span>hr<span class="br0">&#41;</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw1">raise</span> EJwsclAdSetPropertyException.<span class="me1">CreateFmtEx</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span class="st0">&#8216;SetObjectAttributes failed to set %s&#8217;</span>, <span class="st0">&#8216;SetPassword&#8217;</span>, ClassName,<br />
&nbsp; &nbsp; &nbsp; <span class="st0">&#8216;JwsclActiveDirectory&#8217;</span>, <span class="nu0">0</span>, hr, <span class="br0">&#91;</span>AdAttrInfo.<span class="me1">pszAttrName</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</div>
 <span class="post2pdf_span" style="border: 1px solid gray; width: 160px; text-align: left; "><a href="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/generate.php?post=7" rel="nofollow"><img src="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/icon/pdf.png" width="16px" height="16px" />convert this post to pdf.</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/03/30/random-active-directory-notes-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Windows Resource Strings</title>
		<link>http://www.remkoweijnen.nl/blog/2010/03/28/using-windows-resource-strings/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=using-windows-resource-strings</link>
		<comments>http://www.remkoweijnen.nl/blog/2010/03/28/using-windows-resource-strings/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 08:45:05 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.remkoweijnen.nl/blog/?p=560</guid>
		<description><![CDATA[A few days ago I wrote about Using Windows Dialogs in your own programs, wouldn&#8217;t it be nice to be able to use Windows Resource Strings for the same reasons? Loading a resource string is not difficult, let&#8217;s look at some examples: function LoadResourceString&#40;const DllName: String; ResourceId: Integer&#41;: String; var &#160; hDLL: THandle; &#160; Buffer: [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago I wrote about Using <a href="http://www.remkoweijnen.nl/blog/2010/03/24/using-windows-dialogs-from-delphi/" target="_blank">Windows Dialogs</a> in your own programs, wouldn&#8217;t it be nice to be able to use Windows Resource Strings for the same reasons?</p>
<p>Loading a resource string is not difficult, let&#8217;s look at some examples:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">function</span> LoadResourceString<span class="br0">&#40;</span><span class="kw1">const</span> DllName: <span class="kw4">String</span>; ResourceId: <span class="kw4">Integer</span><span class="br0">&#41;</span>: <span class="kw4">String</span>;<br />
<span class="kw1">var</span><br />
&nbsp; hDLL: <span class="kw4">THandle</span>;<br />
&nbsp; Buffer: <span class="kw1">array</span><span class="br0">&#91;</span><span class="nu0">0</span>..<span class="me1">MAX_PATH</span><span class="br0">&#93;</span> <span class="kw1">of</span> <span class="kw4">Char</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; hDLL := LoadLibrary<span class="br0">&#40;</span><span class="kw4">PChar</span><span class="br0">&#40;</span>DllName<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">if</span> hDLL = <span class="nu0">0</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">Exit</span>;</p>
<p>&nbsp; <span class="kw1">if</span> LoadString<span class="br0">&#40;</span>hDll, ResourceId, Buffer, <span class="kw3">Length</span><span class="br0">&#40;</span>Buffer<span class="br0">&#41;</span><span class="br0">&#41;</span> &gt; <span class="nu0">0</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; Result := Buffer;<br />
<span class="kw1">end</span>;</div>
<p>This uses the <a href="http://msdn.microsoft.com/en-us/library/ms647486%28VS.85%29.aspx" target="_self">LoadString</a> api to load a Resource String from an Executable or Dll by it&#8217;s resource Id. An Example might call might be:</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp;LoadResourceString<span class="br0">&#40;</span><span class="st0">&#8216;dsadmin.dll&#8217;</span>, <span class="nu0">226</span><span class="br0">&#41;</span></div>
<p>This loads the string with ResourceId 226 from dsadmin.dll(.mui):</p>
<div class="dean_ch" style="white-space: wrap;">STRINGTABLE<br />
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US<br />
<span class="br0">&#123;</span><br />
<span class="nu0">224</span>, &nbsp;<span class="st0">&quot;Windows cannot complete the password change for %2 because:<span class="es0">\n</span>%1&quot;</span><br />
<span class="nu0">225</span>, &nbsp;<span class="st0">&quot;Windows cannot access object %2 because:<span class="es0">\n</span>%1The object may have been deleted by another administrator in this enterprise.&quot;</span><br />
<span class="nu0">226</span>, &nbsp;<span class="st0">&quot;The New and Confirm passwords must match. Please re-type them.&quot;</span><br />
<span class="nu0">228</span>, &nbsp;<span class="st0">&quot;Object %2 has been disabled.&quot;</span><br />
<span class="nu0">229</span>, &nbsp;<span class="st0">&quot;Windows cannot disable object %2 because:<span class="es0">\n</span>%1&quot;</span><br />
<span class="nu0">231</span>, &nbsp;<span class="st0">&quot;Object %2 has been enabled.&quot;</span><br />
<span class="nu0">232</span>, &nbsp;<span class="st0">&quot;Windows cannot enable object %2 because:<span class="es0">\n</span>%1&quot;</span><br />
<span class="nu0">233</span>, &nbsp;<span class="st0">&quot;Create a new object&#8230;&quot;</span><br />
<span class="nu0">237</span>, &nbsp;<span class="st0">&quot;Mo&amp;amp;ve&#8230;<span class="es0">\n</span>Moves the selected object&quot;</span><br />
<span class="nu0">238</span>, &nbsp;<span class="st0">&quot;The password for %2 cannot be set due to insufficient privileges. Windows will attempt to disable this account. If this attempt fails, the account will become a security risk. Contact an administrator as soon as possible to repair this. Before this user can log on, the password should be set, and the account must be enabled.&quot;</span><br />
<span class="br0">&#125;</span></div>
<p>As you can see in this example, some resource strings have identifiers such as %1 and %2 which are used in the <a href="http://msdn.microsoft.com/en-us/library/ms679351%28VS.85%29.aspx" target="_blank">FormatMessage</a> Api. How can we use that from Delphi?</p>
<p>I wrote a very simple wrapper for it:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">function</span> FormatMsg<span class="br0">&#40;</span><span class="kw1">const</span> Source: <span class="kw4">String</span>; <span class="kw1">const</span> Args: <span class="kw1">array</span> <span class="kw1">of</span> <span class="kw1">const</span><span class="br0">&#41;</span>: <span class="kw4">String</span>;<br />
<span class="kw1">var</span><br />
&nbsp; i: <span class="kw4">Integer</span>;<br />
&nbsp; ArgArray: <span class="kw1">array</span> <span class="kw1">of</span> <span class="kw4">Pointer</span>;<br />
&nbsp; Buffer: <span class="kw4">PChar</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="kw1">for</span> i := <span class="kw3">Low</span><span class="br0">&#40;</span>Args<span class="br0">&#41;</span> <span class="kw1">to</span> <span class="kw3">High</span><span class="br0">&#40;</span>Args<span class="br0">&#41;</span> <span class="kw1">do</span><br />
&nbsp; <span class="kw1">begin</span><br />
&nbsp; &nbsp; <span class="kw3">SetLength</span><span class="br0">&#40;</span>ArgArray, i<span class="nu0">+1</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">case</span> Args<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">VType</span> &nbsp;<span class="kw1">of</span><br />
&nbsp; &nbsp; &nbsp; vtExtended:; <span class="co1">// not supported, should raise Exception</span><br />
&nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; ArgArray<span class="br0">&#91;</span>i<span class="br0">&#93;</span> := Args<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">VPointer</span>;<br />
&nbsp; &nbsp; <span class="kw1">end</span>;<br />
&nbsp; <span class="kw1">end</span>;</p>
<p>&nbsp; <span class="kw1">if</span> FormatMessage<span class="br0">&#40;</span>FORMAT_MESSAGE_FROM_STRING <span class="kw1">or</span><br />
&nbsp; &nbsp; FORMAT_MESSAGE_ALLOCATE_BUFFER <span class="kw1">or</span> FORMAT_MESSAGE_ARGUMENT_ARRAY,<br />
&nbsp; &nbsp; <span class="kw4">PChar</span><span class="br0">&#40;</span>Source<span class="br0">&#41;</span>, <span class="nu0">0</span>, <span class="nu0">0</span>, @Buffer, <span class="nu0">0</span>, @ArgArray<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span> &gt; <span class="nu0">0</span> <span class="kw1">then</span><br />
&nbsp; <span class="kw1">begin</span><br />
&nbsp; &nbsp; Result := Buffer;<br />
&nbsp; &nbsp; <span class="co1">// replace \n (linefeed) with #13#10</span><br />
&nbsp; &nbsp; Result := <span class="kw3">StringReplace</span><span class="br0">&#40;</span>Result, <span class="st0">&#8216;\n&#8217;</span>, <span class="re1">#<span class="nu0">13</span></span><span class="re1">#<span class="nu0">10</span></span>, <span class="br0">&#91;</span>rfReplaceAll<span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; LocalFree<span class="br0">&#40;</span><span class="kw4">DWORD</span><span class="br0">&#40;</span>Buffer<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">end</span><br />
&nbsp; <span class="kw1">else</span> <span class="kw1">begin</span><br />
&nbsp; &nbsp; <span class="kw3">SetLength</span><span class="br0">&#40;</span>Result, <span class="nu0">0</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">end</span>;<br />
<span class="kw1">end</span>;</div>
<p>And here is a usage example:</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp;Memo1.<span class="me1">Lines</span>.<span class="me1">Add</span> <span class="br0">&#40;</span>FormatMsg<span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&#8216;Windows cannot complete the password change for %2 because:\n%1&#8242;</span>,<br />
&nbsp; &nbsp; <span class="br0">&#91;</span><span class="st0">&#8216;the password doesn&#8217;</span><span class="st0">&#8216;t meet complexity requirements&#8217;</span>, <span class="st0">&#8216;John Doe&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
<p>The Result of this is:</p>
<p>Windows cannot complete the password change for John Doe because:<br />
the password doesn&#8217;t meet complexity requirements</p>
 <span class="post2pdf_span" style="border: 1px solid gray; width: 160px; text-align: left; "><a href="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/generate.php?post=0" rel="nofollow"><img src="http://www.remkoweijnen.nl/blog/wp-content/plugins/post2pdf/icon/pdf.png" width="16px" height="16px" />convert this post to pdf.</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.remkoweijnen.nl/blog/2010/03/28/using-windows-resource-strings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
