<?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>JEDI Windows API</title>
	<atom:link href="http://blog.delphi-jedi.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.delphi-jedi.net</link>
	<description>Joint Endeavor of Delphi Innovators of Windows Programming</description>
	<lastBuildDate>Sat, 21 Aug 2010 05:44:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Using Windows 7 Taskbar-features via components</title>
		<link>http://blog.delphi-jedi.net/2010/08/18/using-windows-7-taskbar-features-via-components/</link>
		<comments>http://blog.delphi-jedi.net/2010/08/18/using-windows-7-taskbar-features-via-components/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 04:39:49 +0000</pubDate>
		<dc:creator>Chaosben</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[Window]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows 7]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=770</guid>
		<description><![CDATA[Windows 7 gave us some nice and useful little eye-catchers in the taskbar. Those are available using the Windows shell interfaces ITaskbarList3 and ITaskbarList4. But alas, how can a Delphi developer incorporate these in his applications? You may read on if you ever wanted to&#8230; have this cool progress bar feature in the taskbar. have [...]]]></description>
			<content:encoded><![CDATA[<p>Windows 7 gave us some nice and useful little eye-catchers in the taskbar. Those are available using the Windows shell interfaces <a href="http://msdn.microsoft.com/en-us/library/dd391692%28v=VS.85%29.aspx" target="_blank">ITaskbarList3</a> and <a href="http://msdn.microsoft.com/en-us/library/dd562040%28VS.85%29.aspx">ITaskbarList4</a>. <br />
 But alas, how can a Delphi developer incorporate these in his applications?</p>
<p><span id="more-770"></span>You may read on if you ever wanted to&#8230;</p>
<ol>
<li>have this cool progress bar feature in the taskbar.</li>
<li>have an overlay icon onto your application&#8217;s icon in the taskbar.</li>
<li>multiple tabs for each window or control of your application in the taskbar.</li>
<li>have thumb buttons inside the preview of your form (like the Windows MediaPlayer).</li>
</ol>
<p>You want your application to look like that?</p>
<p><a href="http://blog.delphi-jedi.net/wp-content/uploads/2010/08/Screen1.png" rel="lightbox[770]" title="Using Windows 7 Taskbar-features via components"><img class="aligncenter size-full wp-image-804" src="http://blog.delphi-jedi.net/wp-content/uploads/2010/08/Screen1.png" alt="" width="421" height="203" /></a></p>
<p>Are you using Windows 7? What a lucky (wo)man you are.</p>
<p>The guys from <a href="http://code.google.com/p/theunknownones/" target="_blank">TheUnknownOnes</a> just released some components to use the new features introduced in Windows 7.  <br />
 Of course, these components are based on the JEDI Windows API. At the moment (until the next release of JWAPI), you&#8217;ll have to checkout the trunk of the JWAPI in order to get the code compiled. <br />
 To get these components, checkout <a href="http://theunknownones.googlecode.com/svn/trunk/Components/TaskBarList/" target="_blank">the source</a> out of their svn repository.</p>
<p>And if you want to discuss something about them in German: use <a href="http://www.delphipraxis.net/153782-taskbarlistcomponents-fuer-windows-7-a.html" target="_blank">this thread</a>.</p>
<p>A first short demo was published <a href="http://vimeo.com/14291783" target="_blank">here</a>. Stay tuned for some more.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/08/18/using-windows-7-taskbar-features-via-components/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>TRegistry.DeleteKey and 64bit</title>
		<link>http://blog.delphi-jedi.net/2010/08/17/tregistry-deletekey-and-64bit/</link>
		<comments>http://blog.delphi-jedi.net/2010/08/17/tregistry-deletekey-and-64bit/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 12:51:19 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[64bit]]></category>
		<category><![CDATA[Registry]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=784</guid>
		<description><![CDATA[I got a bug from someone who told me that he had problems with the TRegistry method DeleteKey on his 64bit Windows. It just didn&#8217;t delete a 64bit key* from the registry although he used the KEY_WOW64_64KEY flag in desired access parameter of  TRegistry.Create. At first I thought that it was a problem with the [...]]]></description>
			<content:encoded><![CDATA[<p>I got a bug from someone who told me that he had problems with the TRegistry method <a href="http://docwiki.embarcadero.com/VCL/en/Registry.TRegistry.DeleteKey" target="_blank"><em>DeleteKey</em></a> on his 64bit Windows. It just didn&#8217;t delete a 64bit key* from the registry although he used the KEY_WOW64_64KEY flag in desired access parameter of  TRegistry.Create.</p>
<p><span id="more-784"></span></p>
<p>At first I thought that it was a problem with the OpenKey function of TRegistry. However, this was already confirmed and fixed as a bug in <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=23429" target="_blank">QC# 23429</a>.</p>
<p>Then I wanted to check the real error value of DeleteKey. Of course, it just returns true or false, so I added a call to GetLastError. And it returned 87 (Invalid Parameter). It must be said that using GetLastError in a framework like VCL is always a problem because you don&#8217;t really know how many winapi functions are called subsequent to the actual winapi function. So you may get an error value from another random function. This is one reason I&#8217;m using exceptions in JWSCL, btw.<br />
 A quick step through debugging session (you have to enable debug dcu in project options and rebuild the project) confirmed that the invalid parameter error (87) came from RegDeleteKey. But why 87? The next step was obvious because I had a windows function and thus I would have to read its <a href="http://msdn.microsoft.com/en-us/library/ms724845%28VS.85%29.aspx" target="_blank">MSDN documentation</a>.</p>
<p>It reads:</p>
<div>
<blockquote><p><cite><strong>RegDeleteKey </strong>Function<br />
 Deletes a subkey and its values. Note that key names are not case sensitive. <strong> </strong></cite></p>
<p><strong>64-bit Windows: </strong>On WOW64, 32-bit  applications view a registry tree that is separate from the registry  tree that 64-bit applications view. To enable an application to delete  an entry in the alternate registry view, use the <a id="ctl00_MTCS_main_ctl01" onclick="javascript:Track('ctl00_MTCS_main_ctl00|ctl00_MTCS_main_ctl01',this);" href="http://msdn.microsoft.com/en-us/library/ms724847%28VS.85%29.aspx"><strong>RegDeleteKeyEx</strong></a> function.</p>
</blockquote>
<p><br class="spacer_" /></p>
<p>So the RegDeleteKey<strong>Ex</strong> function must be used. But don&#8217;t stop reading here and implement it. We can&#8217;t just use this function because MSDN states that this function is only available in XP 64bit or Vista (32 and 64bit). So this gets more complicated and I suggest this way :</p>
<table border="1">
<tbody>
<tr>
<td></td>
<td>XP 32bit</td>
<td>XP 64bit</td>
<td>Vista and newer (32+64)</td>
</tr>
<tr style="text-align: center;">
<td style="text-align: left;">RegDeleteKey</td>
<td>√</td>
<td>only 32bit keys</td>
<td>only 32bit keys</td>
</tr>
<tr>
<td>RegDeleteKeyEx</td>
<td>unsupported</td>
<td style="text-align: center;">√</td>
<td style="text-align: center;">√</td>
</tr>
</tbody>
</table>
<p>√ &#8211; will run fine as it is intended.</p>
<ul>
<li>On a 64bit Windows, always call RegDeleteKeyEx. It supports both 32bit and 64bit registry keys.</li>
<li>Otherwise, if you don&#8217;t want to delete 64bit keys:
<ul>
<li>Call RegDeleteKeyEx on Vista or newer, though.</li>
<li>Call RegDeleteKey on XP 32bit. </li>
</ul>
</li>
</ul>
<p>As a conclusion, you cannot use the TRegistry method DeleteKey with 64bit registry keys. Either you have to use your own RegDeleteKeyEx call or just use a derived class of TRegistry. Of course this is only necessary it you want to access 64bit keys&#8230;this article is FYI.</p>
<p>In the end, the question arises to me why RegDeleteKey does not support 64bit registry keys. I couldn&#8217;t find any evidences, so I can only use my brain to think of one:<br />
 Well, the RegDeleteKey function can be really dangerous if a 32bit application, that is not aware of 64bit, erases 64bit keys. This is especially true for &#8220;HKEY_LOCAL_MACHINE\SOFTWARE&#8221; because you may have installed two versions of an application with same name. First you installed a 32bit only application (name it X) you bought several years ago for your 32bit Windows. One day the vendor sends you a 64bit only update that you install (*so happy*). You decide to abandon the 32bit version and call its custom made uninstaller which deletes all of its known keys. Of course, it will also delete the 64bit version. This may be fictional but possible without the breakup of 32bit and 64bit keys in heavily used parts of the registry. So RegDeleteKey will not delete the 64bit keys because that would break 64bit applications. It seems to me that Microsoft experienced it already, before they decided to add 32-64bit registry separation.  Maybe Raymond Chen would say something like this: <em>Believe us, we tried the other way around:  it&#8217;s worse</em>.</p>
<p><br class="spacer_" /></p>
<p>If you are interested in more information, I suggest you to read <a href="http://msdn.microsoft.com/en-us/library/aa384129%28VS.85%29.aspx" target="_blank">Accessing an Alternate Registry View</a>.</p>
<p>* The key was a subkey from &#8220;HKEY_LOCAL_MACHINE\SOFTWARE&#8221;. In 64bit Windows, a 32bit application (not aware of 64bit) will only see the contents of &#8220;HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node&#8221;.</p>
<h3>Update</h3>
<p>I submitted a bug report to QC: <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=87323" target="_blank">#87323</a></p>
<h3>Links</h3>
<ul>
<li><a href="http://www.delphipraxis.net/127364-registry-deletekey-problem-unter-xp64.html" target="_blank">DelphiPraxis</a></li>
</ul>
</div>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/08/17/tregistry-deletekey-and-64bit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows LNK Exploit</title>
		<link>http://blog.delphi-jedi.net/2010/07/19/windows-lnk-exploit/</link>
		<comments>http://blog.delphi-jedi.net/2010/07/19/windows-lnk-exploit/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 10:37:18 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=751</guid>
		<description><![CDATA[As you maybe have heard already. There is a shell exploit that is executed when Windows shows just the icon from a link file. MS works on it but currently you can only remove the icon handler key from the registry to be &#8220;safe&#8221;. See this link. It also tells us the impact of the [...]]]></description>
			<content:encoded><![CDATA[<p>As you maybe have heard already. There is a shell exploit that is executed when Windows shows just the icon from a link file. MS works on it but currently you can only remove the icon handler key from the registry to be &#8220;safe&#8221;. See this <a href="http://www.microsoft.com/technet/security/advisory/2286198.mspx" target="_blank">link</a>. It also tells us the impact of the action. However, on Windows 7, I think this prevents me from working efficiently with the Windows Explorer.<span id="more-751"></span><a href="http://www.microsoft.com/technet/security/advisory/2286198.mspx" target="_blank"> Technet reads:</a></p>
<p><cite><strong>Impact of workaround.</strong>Disabling icons from being displayed for  shortcuts prevents the issue from being exploited on affected systems.  When this workaround is implemented, shortcut files and Internet  Explorer shortcuts will no longer have an icon displayed.</cite></p>
<p>Let me show you, why I can&#8217;t work anymore efficiently.</p>
<div id="attachment_752" class="wp-caption alignnone" style="width: 471px"><a href="http://blog.delphi-jedi.net/wp-content/uploads/2010/07/StartMenuWin7Clear.png" rel="lightbox[751]" title="StartMenuWin7Clear"><img class="size-full wp-image-752 " title="StartMenuWin7Clear" src="http://blog.delphi-jedi.net/wp-content/uploads/2010/07/StartMenuWin7Clear.png" alt="Windows 7 Taskbar with plain Icons" width="461" height="30" /></a><p class="wp-caption-text">Windows 7 Taskbar with plain Icons</p></div>
<p>As you can see, some of the applications are already started and they don&#8217;t have their icon but some of them have. I don&#8217;t see the reason though. Do you?</p>
<p>BTW: This goes on in the start menu, on the desktop, and the favorite list in Windows Explorer.</p>
<p>Happy working&#8230;.  <img src='http://blog.delphi-jedi.net/wp-includes/images/smilies/icon_twisted.gif' alt=':twisted:' class='wp-smiley' /> </p>
<p>EDIT:</p>
<p>A <a href="http://code.google.com/p/linkiconshim/" target="_blank">possible fix</a> was supplied by external programmers. Maybe this will be the only option for the last few people who are using Windows 2000 still.</p>
<p><br class="spacer_" /></p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/07/19/windows-lnk-exploit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Useful scripts for MSVC and C++ Builder users …</title>
		<link>http://blog.delphi-jedi.net/2010/06/24/useful-scripts-for-msvc-and-c-builder-users-%e2%80%a6/</link>
		<comments>http://blog.delphi-jedi.net/2010/06/24/useful-scripts-for-msvc-and-c-builder-users-%e2%80%a6/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 12:10:57 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=742</guid>
		<description><![CDATA[Assarbad wrote this script some time ago to compile and link C++ projects on the command line easier. I adapted the cmd script for VC++2010 and also for C++ Builder 2009/2010 and now I have been using it for quite some time. So I wanted to give it back to the community. Feel free to [...]]]></description>
			<content:encoded><![CDATA[<p>Assarbad wrote this <a href="http://blog.assarbad.net/20090116/useful-script-for-msvc-users/" target="_blank">script</a> some time ago to compile and link C++ projects on the command line easier. I adapted the cmd script for VC++2010 and also for C++ Builder 2009/2010 and now I have been using it for quite some time. So I wanted to give it back to the community.</p>
<p><span id="more-742"></span>Feel free to use it since it is public domain.</p>
<p><a href="http://blog.delphi-jedi.net/wp-content/uploads/2010/06/scripts.zip">Download C++ Environment Scripts</a></p>
<p>By default the scripts setup the environment to the newest compiler found on your system. In this way you can just call msbuild and build your projects.</p>
<p><br class="spacer_" /></p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/06/24/useful-scripts-for-msvc-and-c-builder-users-%e2%80%a6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting Folder Security</title>
		<link>http://blog.delphi-jedi.net/2010/03/24/setting-folder-security/</link>
		<comments>http://blog.delphi-jedi.net/2010/03/24/setting-folder-security/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 18:03:38 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[ACL]]></category>
		<category><![CDATA[DACL]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[permission]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=721</guid>
		<description><![CDATA[This article describes some ways how to set the security on a folder using JWSCL. Usually, we want to add some rights for a particular user to a folder so she gets access. I can say that is a heck of work to do with WinAPI. But still with JWSCL we need to consider some [...]]]></description>
			<content:encoded><![CDATA[<p>This article describes some ways how to set the security on a folder using JWSCL. Usually, we want to add some rights for a particular user to a folder so she gets access. I can say that is a heck of work to do with WinAPI. But still with JWSCL we need to consider some things. <span id="more-721"></span></p>
<p>The following code creates a folder named &#8220;JWSCLTest&#8221; and applies a DACL that allows full control to everyone. The folder will inherit its security settings to child folders and files (check the afXXX flags).</p>
<p><pre><pre class="brush:delphi">const JWSCLTestFolder = &#039;JWSCLTestFolder&#039;;

var
&nbsp;&nbsp;SD : TJwSecurityDescriptor;
&nbsp;&nbsp;pSA : PSecurityAttributes;
begin
&nbsp;&nbsp;JwInitWellKnownSIDs;

&nbsp;&nbsp;SD := TJwSecurityDescriptor.Create;
&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;SD.DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[afContainerInheritAce, afObjectInheritAce], FILE_ALL_ACCESS, JwWorldSID));

&nbsp;&nbsp;&nbsp;&nbsp;pSA := SD.Create_SA();
&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Win32Check(CreateDirectory(JWSCLTestFolder, pSA));
&nbsp;&nbsp;&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SD.Free_SA(pSA); //remember to free pointer
&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;SD.Free;
&nbsp;&nbsp;end;
end.
</pre></pre></p>
<p>CreateDirectory receives a security attributes structure that is applied to the folder directly. However, in this way the parent security descriptor is not inherited to our folder. This is called a protected DACL because the inheritance flow is stopped. So we get a folder with only one Access Control Entry (ACE) : Everyone (aka World SID).  To remedy that we can copy the ACEs from the parent folder to our own folder:</p>
<p><pre><pre class="brush:delphi">procedure MergeParentDACL(const Location : String; TargetSD : TJwSecurityDescriptor);
var DirSD : TJwSecureFileObject;
begin
&nbsp;&nbsp;DirSD := TJwSecureFileObject.Create(Location);
&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;TargetSD.DACL.AddACEs(DirSD.DACL);
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;DirSD.Free;
&nbsp;&nbsp;end;
end;

var
&nbsp;&nbsp;DirSD : TJwSecureFileObject;

&nbsp;&nbsp;SD, SD2 : TJwSecurityDescriptor;
&nbsp;&nbsp;pSA : PSecurityAttributes;
begin
&nbsp;&nbsp;JwInitWellKnownSIDs;

&nbsp;&nbsp;SD := TJwSecurityDescriptor.Create;

&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;SD.DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[afContainerInheritAce, afObjectInheritAce], FILE_ALL_ACCESS, JwWorldSID));

&nbsp;&nbsp;&nbsp;&nbsp;MergeParentDACL(&#039;.&#039;, SD);

&nbsp;&nbsp;&nbsp;&nbsp;pSA := SD.Create_SA();
&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Win32Check(CreateDirectory(JWSCLTestFolder, pSA));
&nbsp;&nbsp;&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SD.Free_SA(pSA);
&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;SD.Free;
&nbsp;&nbsp;end;
end.
</pre></pre></p>
<p>The function <em>MergeParentDACL</em> receives the location of the parent folder and retrieves its security settings. Then its DACL is copied to the target security descriptor. JWSCL with <em>TargetSD.DACL.AddACEs</em> makes sure that the order of the ACEs are still correct (first deny then allow entries) by moving them accordingly.</p>
<p>In addition, there is a second, much easier way to achieve the same result.</p>
<p><pre><pre class="brush:delphi">var
&nbsp;&nbsp;SD : TJwSecurityDescriptor;
&nbsp;&nbsp;DirSD : TJwSecureFileObject;
begin
&nbsp;&nbsp;JwInitWellKnownSIDs;

&nbsp;&nbsp;Win32Check(CreateDirectory(JWSCLTestFolder, nil));

&nbsp;&nbsp;DirSD := TJwSecureFileObject.Create(JWSCLTestFolder);
&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;SD := DirSD.GetSecurityDescriptor([siDaclSecurityInformation]);
&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SD.DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[afContainerInheritAce, afObjectInheritAce], FILE_ALL_ACCESS, JwWorldSID));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DirSD.SetSecurityDescriptor(SD, [siDaclSecurityInformation]);
&nbsp;&nbsp;&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SD.Free;
&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;DirSD.Free;
&nbsp;&nbsp;end;
</pre></pre></p>
<p>In this way we didn&#8217;t set the security descriptor directly when the folder was created. Nevertheless we get a combination of inheritace ACEs plus the explicit one (JwWorldSID).</p>
<h3>Note</h3>
<p>It is always a good idea to check whether SD.DACL (in above codes) is nil and if so ignore it or create a new and empty one to be used instead. It is always possible that a file or folder comes with a nil DACL which means either no access at all (flag DACLpresent) or everyone has full access (flag DACLpresent not available).</p>
<h3>I used the following JEDI units:</h3>
<p><pre><pre class="brush:delphi">uses
&nbsp;&nbsp;JwaWindows,

&nbsp;&nbsp;JwsclDescriptor,
&nbsp;&nbsp;JwsclTypes,
&nbsp;&nbsp;JwsclConstants,
&nbsp;&nbsp;JwsclKnownSid,
&nbsp;&nbsp;JwsclAcl,
&nbsp;&nbsp;JwsclMapping,
&nbsp;&nbsp;JwsclSecureObjects,
&nbsp;&nbsp;JwsclSid,
</pre></pre></p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/03/24/setting-folder-security/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New JEDI News Server</title>
		<link>http://blog.delphi-jedi.net/2010/03/22/new-jedi-news-server/</link>
		<comments>http://blog.delphi-jedi.net/2010/03/22/new-jedi-news-server/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 15:24:27 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=719</guid>
		<description><![CDATA[As you maybe already know, the old news server for JEDI related questions crashed some time ago. Unfortunately, the old host could not undo the crash and thus some JEDI members created a new server (Thanks you!). The new server location is: news.delphi-jedi.org Please adapt your news reader accordingly. However, it is a pity that [...]]]></description>
			<content:encoded><![CDATA[<p>As you maybe already know, the old news server for JEDI related questions crashed some time ago. Unfortunately, the old host could not undo the crash and thus some JEDI members created a new server (Thanks you!). The new server location is: <span style="font-size: medium;"><strong>news.delphi-jedi.org </strong></span></p>
<p><span id="more-719"></span>Please adapt your news reader accordingly. However, it is a pity that the old messages cannot be restored and maybe never will without an backup.</p>
<p>Furthermore, the server itself may still be changed but the address will stay the same.</p>
<p><br class="spacer_" /></p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/03/22/new-jedi-news-server/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Embarcadero Forum Access</title>
		<link>http://blog.delphi-jedi.net/2010/03/22/embarcadero-forum-access/</link>
		<comments>http://blog.delphi-jedi.net/2010/03/22/embarcadero-forum-access/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 09:50:57 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=715</guid>
		<description><![CDATA[If you are accessing the Embarcadero Forums and such through an Offline Reader like Mozilla Thunderbird, you probably have had a connection problem for some time now. I don&#8217;t know what the reason is. However, as a solution instead, use the address forums.embarcadero.com and don&#8217;t forget to activate SSL. I couldn&#8217;t make a connection without [...]]]></description>
			<content:encoded><![CDATA[<p>If you are accessing the Embarcadero Forums and such through an Offline Reader like Mozilla Thunderbird, you probably have had a connection problem for some time now. I don&#8217;t know what the reason is. However, as a solution instead, use the address <strong>forums.embarcadero.com</strong> and don&#8217;t forget to activate SSL. I couldn&#8217;t make a connection without it.</p>
<p><span id="more-715"></span>UPDATE:</p>
<p>It looks to me as if only the unsecured access is not accepted. Instead only SSL is available regardless of the address (so both works).<br />
I got some mails from people who couldn&#8217;t answer the threads I participate. So they sent me mails directly. </p>
<p>A shame that Kaster&#8217;s thread wasn&#8217;t replicated by e.g. Nick. His blog is far more often read by people than this Announce forum (which was afterwards effectively unavailable to me and others).<br />
Furthermore some forums look to me a little bit more abandoned than usual. So the activity seems to be lower.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/03/22/embarcadero-forum-access/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What is GetEffectiveRightsFromAcl for? #2</title>
		<link>http://blog.delphi-jedi.net/2010/03/13/what-is-geteffectiverightsfromacl-for-2/</link>
		<comments>http://blog.delphi-jedi.net/2010/03/13/what-is-geteffectiverightsfromacl-for-2/#comments</comments>
		<pubDate>Sat, 13 Mar 2010 21:04:43 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[JWSCL]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=701</guid>
		<description><![CDATA[A long time ago I wrote an article about this strange WinAPI function called GetEffectiveRightsFromAcl. There was a problem that I showed how to solve (see my article and the comment in the MSDN doc). However, this function has never been a good way for retrieving the possible access mask. It seems that MS has [...]]]></description>
			<content:encoded><![CDATA[<p>A long time ago I wrote an <a href="http://blog.delphi-jedi.net/2008/09/10/what-is-geteffectiverightsfromacl-for/" target="_blank">article</a> about this strange WinAPI function called <a href="http://msdn.microsoft.com/en-us/library/aa446637%28VS.85%29.aspx" target="_blank">GetEffectiveRightsFromAcl</a>. There was a problem that I showed how to solve (see my article and the comment in the MSDN doc). However, this function has never been a good way for retrieving the possible access mask. It seems that MS has changed the MSDN article of this function and instead wrote an example that uses the MS Authz API. I translated the example but using JWSCL. You can see yourself how different it looks&#8230;</p>
<p><span id="more-701"></span></p>
<p>I have added some comments to the source code itself so you can read a description directly in the code.</p>
<p><pre><pre class="brush:delphi">program GetEffectiveRightsFromAclTest;

uses
&nbsp;&nbsp;JwaWindows,
&nbsp;&nbsp;JwsclKnownSid,
&nbsp;&nbsp;JwsclConstants,
&nbsp;&nbsp;JwsclTypes,
&nbsp;&nbsp;JwsclExceptions,
&nbsp;&nbsp;JwsclSecureObjects,
&nbsp;&nbsp;JwsclSid,
&nbsp;&nbsp;JwsclDescriptor,
&nbsp;&nbsp;JwsclAuthCtx,
&nbsp;&nbsp;JwsclMapping,
&nbsp;&nbsp;JwsclUtils,
&nbsp;&nbsp;JwsclACL,

&nbsp;&nbsp;Dialogs,
&nbsp;&nbsp;SysUtils;

//computes granted access mask for a security descriptor and a SID
//An error is thrown by an exception - typical JWSCL
function GetEffectiveAccess(const SD : TJwSecurityDescriptor;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const Sid : TJwSecurityId) : DWORD;
var
&nbsp;&nbsp;AuthRM : TJwAuthResourceManager;
&nbsp;&nbsp;AuthCtx : TJwAuthContext;
&nbsp;&nbsp;AuthReply : TJwAuthZAccessReply;
&nbsp;&nbsp;Request : TJwAuthZAccessRequest;
begin
&nbsp;&nbsp;//The following code uses the MS AuthZ API
&nbsp;&nbsp;//JWSCL wraps the function calls
&nbsp;&nbsp;AuthRM := TJwAuthResourceManager.Create(&#039;&#039;, [], nil, nil);
&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;//Tell AuthZ to use a SID for access checking
&nbsp;&nbsp;&nbsp;&nbsp;//We also could use a token and prevent the problem of
&nbsp;&nbsp;&nbsp;&nbsp;// restricted Administrators in Vista/7
&nbsp;&nbsp;&nbsp;&nbsp;AuthCtx := TJwAuthContext.CreateBySid(AuthRM, [], Sid, 0, nil);
&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//As documented AccessCheck returns a GrantedAccessMask
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;when using MAXIMUM_ALLOWED
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Request := TJwAuthZAccessRequest.Create(MAXIMUM_ALLOWED,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JwNullSID, nil, nil, shOwned);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//does the access check using a generic mapping to file/folder
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AuthCtx.AccessCheck(0, Request, 0, SD, nil,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TJwSecurityFileFolderMapping, AuthReply, nil);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//return the granted access mask
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result := AuthReply.GrantedAccessMask[0];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Request.Free;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AuthCtx.Free;
&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;AuthRM.Free;
&nbsp;&nbsp;end;
end;

//computes granted access mask for a file and username
//An error is thrown by an exception - typical JWSCL
function GetEffectiveAccessFromFile(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const FileName,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DomainName, UserName : string) : DWORD;
var
&nbsp;&nbsp;F : TJwSecureFileObject;
&nbsp;&nbsp;SD : TJwSecurityDescriptor;
&nbsp;&nbsp;Flags : TJwSecurityInformationFlagSet;
&nbsp;&nbsp;Sid : TJwSecurityId;
begin
&nbsp;&nbsp;//Translate username and domainname into a SID
&nbsp;&nbsp;//Throws an EJwsclWinCallFailedException if
&nbsp;&nbsp;//&nbsp;&nbsp;the username could not be translated
&nbsp;&nbsp;Sid := TJwSecurityId.Create(DomainName, UserName);
&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;F := TJwSecureFileObject.Create(FileName);
&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//adding siLabelSecurityInformation makes no sense
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;since it cannot be checked against a simple SID
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Flags := [siOwnerSecurityInformation,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;siGroupSecurityInformation,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;siDaclSecurityInformation];

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//get the security descriptor (result is not cached)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SD := F.GetSecurityDescriptor(Flags);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result := GetEffectiveAccess(SD, Sid);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SD.Free;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F.Free;
&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;Sid.Free;
&nbsp;&nbsp;end;
end;

const
&nbsp;&nbsp;Target = &#039;C:\Windows&#039;;
&nbsp;&nbsp;UserName = &#039;Christian&#039;;

var AccessMask : TJwAccessMask;
begin
&nbsp;&nbsp;JwInitWellKnownSIDs;

&nbsp;&nbsp;AccessMask := GetEffectiveAccessFromFile(Target, &#039;&#039;, UserName);
&nbsp;&nbsp;ShowMessage(Format(&#039;File/Folder: %s&#039;#13#10&#039;User: %s&#039;#13#10&#039;%s&#039;,
&nbsp;&nbsp;&nbsp;&nbsp;[Target,
&nbsp;&nbsp;&nbsp;&nbsp; UserName,
&nbsp;&nbsp;&nbsp;&nbsp; JwFormatAccessRights(AccessMask, FileFolderMapping)]));
end.
</pre></pre></p>
<p>Be aware that the code does the same as GetEffectiveRightsFromAcl.</p>
<h3>Restricted Administrator account in Vista/7</h3>
<p>Also it does not take into account a restricted Vista account. The reason is that the privileges of an Administrator account are stripped away only when a user logs on. So the account management does not behave differently to Windows XP. Since we use an account name the function only finds the Administrators group in the membership list of the user. Thus we may see a fullly granted access mask as a result when using the function on e.g. the Windows folder.</p>
<h3>Integrity Level in Vista/7</h3>
<p>Of course, we cannot use the mandatory label (notice <em>siLabelSecurityInformation</em>) of a file or folder because the integrity level of the user is only known when she is logged on. Thus if a folder has a high integrity level, the function will still return full access control even if the user cannot write access (no-write-up) the folder when logged on.</p>
<h3>Download</h3>
<p>Download <a href="http://blog.delphi-jedi.net/wp-content/uploads/2010/03/GetEffectiveRightsFromAclWithAuthZ.zip">GetEffectiveRightsFromAclWithAuthZ</a>.pas</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/03/13/what-is-geteffectiverightsfromacl-for-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Site Recommendation: History of Windows</title>
		<link>http://blog.delphi-jedi.net/2010/03/13/site-recommondation-history-of-windows/</link>
		<comments>http://blog.delphi-jedi.net/2010/03/13/site-recommondation-history-of-windows/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 23:13:27 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[Recommendation]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=697</guid>
		<description><![CDATA[If you are interested in the history of Windows, as I am, you should read the article The Secret Origin of Windows by Tandy Trower the product manager of Windows 1.0. This article gives a deep insight into the journey Tandy and his developers had to endure to bring a product on the market that [...]]]></description>
			<content:encoded><![CDATA[<p>If you are interested in the history of Windows, as I am, you should read the article<a href="http://technologizer.com/2010/03/08/the-secret-origin-of-windows/" target="_blank"> <strong>The Secret Origin of Windows</strong></a> by Tandy Trower the product manager of Windows 1.0. This article gives a deep insight into the journey Tandy and his developers had to endure to bring a product on the market that should change the world (although it took a while).</p>
<p><span id="more-697"></span>Tandy also mentions the competitor Borland with its famous Turbo Pascal (that I also used) and how it got Bill Gates to tremble.</p>
<p><cite>At $50 for the Borland product vs. the Microsoft $400 compiler, it was a bit like comparing a VW to a Porsche. But while Turbo Pascal was lighter weight for serious development, it was almost as quick for programming and debugging as Microsoft’s BASIC interpreters</cite></p>
<p>I wonder if the comment about the speed is true?</p>
<p>And did you know that Microsoft had been using the language Pascal for their projects until they developed C ?</p>
<p>Read more about <a onclick="pageTracker._trackPageview ('/outgoing/http_technologizer_com_2010_03_08_the_secret_origin_of_windows_');" rel="nofollow" href="http://technologizer.com/2010/03/08/the-secret-origin-of-windows/" target="_blank">The Secret Origin of Windows</a></p>
<p><br class="spacer_" /></p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/03/13/site-recommondation-history-of-windows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Retrieving File Owner</title>
		<link>http://blog.delphi-jedi.net/2010/03/11/retrieving-file-owner/</link>
		<comments>http://blog.delphi-jedi.net/2010/03/11/retrieving-file-owner/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 13:52:11 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=676</guid>
		<description><![CDATA[This article is about how to retrieve the owner of a file. If you are experienced with some of the WinAPI security function this can be pretty easy. There are some problems that needs to be addressed though. The first one is the size of the security items like the SID name of the owner. [...]]]></description>
			<content:encoded><![CDATA[<p>This article is about how to retrieve the owner of a file. If you are experienced with some of the WinAPI security function this can be pretty easy. There are some problems that needs to be addressed though. The first one is the size of the security items like the SID name of the owner. Secondly, there is the possibility that a SID cannot be resolved to a human readable name at all. And thirdly, we need to check all the result values.</p>
<p><span id="more-676"></span></p>
<h2>WinAPI</h2>
<p><pre><pre class="brush:delphi">
uses
&nbsp;&nbsp;SysUtils,
&nbsp;&nbsp;//JwaWindows, //Use either JwaWindows or these JEDI headers:
&nbsp;&nbsp;JwaWinBase,
&nbsp;&nbsp;JwaWinType,
&nbsp;&nbsp;JwaWinNT,
&nbsp;&nbsp;JwaAclApi,
&nbsp;&nbsp;JwaAccCtrl,
&nbsp;&nbsp;JwaWinError,
&nbsp;&nbsp;JwaSddl;

type
&nbsp;&nbsp;TOwnerResult = (orNone, orName, orSID);

function GetFileOwner(const FileName: string;
&nbsp;&nbsp;out Domain, Username: String): TOwnerResult;
var
&nbsp;&nbsp;pSD: PSecurityDescriptor;
&nbsp;&nbsp;dwOwnerNameSize, dwDomainNameSize: DWORD;
&nbsp;&nbsp;pOwnerSID: PSID;
&nbsp;&nbsp;pszOwnerName, pszDomainName: PChar;
&nbsp;&nbsp;OwnerType: SID_NAME_USE;
&nbsp;&nbsp;dwError : DWORD;
begin
&nbsp;&nbsp;result := orNone;

&nbsp;&nbsp;pSD := nil;
&nbsp;&nbsp;dwError := GetNamedSecurityInfo(
&nbsp;&nbsp;&nbsp;&nbsp; PChar(FileName),//__in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPTSTR pObjectName,
&nbsp;&nbsp;&nbsp;&nbsp; SE_FILE_OBJECT,//__in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SE_OBJECT_TYPE ObjectType,
&nbsp;&nbsp;&nbsp;&nbsp; OWNER_SECURITY_INFORMATION,//__in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SECURITY_INFORMATION SecurityInfo,
&nbsp;&nbsp;&nbsp;&nbsp; @pOwnerSID,//__out_opt&nbsp;&nbsp;PSID *ppsidOwner,
&nbsp;&nbsp;&nbsp;&nbsp; nil,//__out_opt&nbsp;&nbsp;PSID *ppsidGroup,
&nbsp;&nbsp;&nbsp;&nbsp; nil,//__out_opt&nbsp;&nbsp;PACL *ppDacl,
&nbsp;&nbsp;&nbsp;&nbsp; nil,//__out_opt&nbsp;&nbsp;PACL *ppSacl,
&nbsp;&nbsp;&nbsp;&nbsp; pSD//__out_opt&nbsp;&nbsp;PSECURITY_DESCRIPTOR *ppSecurityDescriptor
&nbsp;&nbsp; );
&nbsp;&nbsp;if (dwError &lt;&gt; NOERROR) then
&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;SetLastError(dwError);
&nbsp;&nbsp;&nbsp;&nbsp;RaiseLastOSError;
&nbsp;&nbsp;end;

&nbsp;&nbsp;//First get necessary memory size for Owner and Domain
&nbsp;&nbsp;dwOwnerNameSize&nbsp;&nbsp;:= 0;
&nbsp;&nbsp;dwDomainNameSize := 0;
&nbsp;&nbsp;if not LookupAccountSID(nil, pOwnerSID, nil,
&nbsp;&nbsp;&nbsp;&nbsp;dwOwnerNameSize, nil, dwDomainNameSize, OwnerType) then
&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;//Check for SIDs that are unknown on this local system
&nbsp;&nbsp;&nbsp;&nbsp;if (GetLastError() = ERROR_NONE_MAPPED) then
&nbsp;&nbsp;&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Win32Check(ConvertSidToStringSid(pOwnerSID, pszOwnerName));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Domain := &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Username := pszOwnerName;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LocalFree(HLOCAL(pszOwnerName));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result := orSID;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit;
&nbsp;&nbsp;&nbsp;&nbsp;end
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;//Any other error exits the function
&nbsp;&nbsp;&nbsp;&nbsp;if (GetLastError() &lt;&gt; ERROR_INSUFFICIENT_BUFFER) then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RaiseLastOsError;
&nbsp;&nbsp;end;

&nbsp;&nbsp;//Allocate memory for owner and domain
&nbsp;&nbsp;//Take into account the size of a char type (like WideCHAR)
&nbsp;&nbsp;GetMem(pszOwnerName, dwOwnerNameSize*sizeof(CHAR));
&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;GetMem(pszDomainName, dwDomainNameSize*sizeof(CHAR));
&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Retrieve name and domain
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Win32Check(LookupAccountSID(nil, pOwnerSID, pszOwnerName,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwOwnerNameSize, pszDomainName, dwDomainNameSize, OwnerType));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result := orName;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Domain&nbsp;&nbsp; := pszDomainName;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Username := pszOwnerName;
&nbsp;&nbsp;&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FreeMem(pszDomainName);
&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;FreeMem(pszOwnerName);
&nbsp;&nbsp;end;
end;
</pre></pre></p>
<p>The function behaves the following:</p>
<ul>
<li>If an WinAPI error occurs the exception EOSError is thrown. You can retrieve the error value from its property Errorcode.</li>
<li>If the user name could be retrieved the result value is <em>orName</em> and both parameter <em>Domain </em>and <em>UserName</em> contain a value. Otherwise the result is orSID and only UserName contains the User Security Identifier (e.g. S-1-5-21-564352346-2735467565-567745764-1001).</li>
</ul>
<h2>JWSCL</h2>
<p>Of course, JWSCL wraps these function calls already. Thus the source size decreases rapidly. See another <a href="http://blog.delphi-jedi.net/2007/10/21/why-jwscl">example here</a>.<br />
In JWSCL it is quite different to implement the function. However the behaviour is equal:</p>
<p><pre><pre class="brush:delphi">function JwsclGetFileOwner(const FileName: string;
&nbsp;&nbsp;out Domain, Username: String): TOwnerResult;
var
&nbsp;&nbsp;F : TJwSecureFileObject;
&nbsp;&nbsp;Owner : TJwSecurityId;
begin
&nbsp;&nbsp;F := TJwSecureFileObject.Create(FileName);
&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;Owner := F.Owner; //Owner is cached/freed by TJwSecureFileObject
&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Domain := Owner.GetAccountDomainName();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Username := Owner.GetAccountName();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result := orName;
&nbsp;&nbsp;&nbsp;&nbsp;except
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on E : EJwsclWinCallFailedException do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if E.LastError = ERROR_NONE_MAPPED then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Domain := &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Username := Owner.StringSID;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result := orSID;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;F.Free;
&nbsp;&nbsp;end;
end;
</pre></pre></p>
<p>In a next version of JWSCL (currently trunk) the exception handling will be a little bit different:</p>
<p><pre><pre class="brush:delphi">function JwsclGetFileOwner2(const FileName: string;
&nbsp;&nbsp;out Domain, Username: String): TOwnerResult;
var
&nbsp;&nbsp;F : TJwSecureFileObject;
&nbsp;&nbsp;Owner : TJwSecurityId;
begin
&nbsp;&nbsp;F := TJwSecureFileObject.Create(FileName);
&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;Owner := F.Owner; //Owner is cached/freed by TJwSecureFileObject
&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Domain := Owner.GetAccountDomainName();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Username := Owner.GetAccountName();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result := orName;
&nbsp;&nbsp;&nbsp;&nbsp;except
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on E : EJwsclSidNotMappedException do //not mapped error is handled differently
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Domain := &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Username := Owner.StringSID;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result := orSID;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;F.Free;
&nbsp;&nbsp;end;
end;
</pre></pre></p>
<p>If you use JWSCL (Version >= 0.9.2a) and enable the compiler switch <strong>JWSCL_SIDCACHE</strong> in file Include\Jwscl.inc, JWSCL will add a SID cache (for all TJwSecurityID instances globally). In this way LookupAccountSid will be called only once for every unknown SID and thus SIDs that were already translated are retrieved from cache instead.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/03/11/retrieving-file-owner/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
