<?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 &#187; JWSCL</title>
	<atom:link href="http://blog.delphi-jedi.net/tag/jwscl/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>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>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>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>
		<item>
		<title>JWSCL and FreeAndNil</title>
		<link>http://blog.delphi-jedi.net/2010/02/25/jwscl-and-freeandnil/</link>
		<comments>http://blog.delphi-jedi.net/2010/02/25/jwscl-and-freeandnil/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 11:54:59 +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=660</guid>
		<description><![CDATA[There is a lot of talking about the usage of FreeAndNil in destructors. I&#8217;ve never thought about it before so I used it quite often even in destructors. Although I don&#8217;t use it as a universal remedy function, it still seems to be a bad design: a thought shared by many leading Delphi experts.  Thus [...]]]></description>
			<content:encoded><![CDATA[<p>There is a lot of talking about the usage of FreeAndNil in destructors. I&#8217;ve never thought about it before so I used it quite often even in destructors. Although I don&#8217;t use it as a universal remedy function, it still seems to be a bad design: a thought shared by many leading Delphi experts.  Thus I refactored the destructors in JWSCL to accompany them.</p>
<p><span id="more-660"></span>I introduced a function similar to FreeAndNil</p>
<p><pre class="brush:delphi">procedure JwFree(var Obj);</pre></p>
<p>It just frees an object&#8230;in the release build of an application. However, in a debug build it additionally sets the value of obj to $C which isn&#8217;t a valid memory address. So &#8220;Assigned&#8221; won&#8217;t work here.<br />
 Any access to this &#8220;freed&#8221; member will generate an AccessViolation at address $0000000C. So you will know that a member of JWSCL was used beyond its life time.</p>
<p><pre><pre class="brush:delphi">procedure JwFree(var Obj);
var
 Temp: TObject;
begin
&nbsp;&nbsp;Temp := TObject(Obj);
{$IFDEF DEBUG}
&nbsp;&nbsp;Pointer(Obj) := Pointer($C);
{$ENDIF DEBUG}
&nbsp;&nbsp;Temp.Free;
end;</pre></pre></p>
<p>I wonder if it should be extended to support different flavors like</p>
<ol>
<li>$C in debug build and don&#8217;t touch the value in release (as currently shown)</li>
<li>Set the value $C also in release mode.</li>
<li>Nil the value in release mode. (quiet death mode)</li>
</ol>
<p>They could be set by a compiler switch. Still have to think about this though&#8230;<br />
 What do you think?</p>
<h2>Changes</h2>
<p>I have commited these changes into the developer branch. They will be published in a next release so the current release won&#8217;t break a bad design.</p>
<p> <img src='http://blog.delphi-jedi.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/02/25/jwscl-and-freeandnil/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>ACTRL_ACCESS Diagram</title>
		<link>http://blog.delphi-jedi.net/2010/02/11/actrl_access-diagram/</link>
		<comments>http://blog.delphi-jedi.net/2010/02/11/actrl_access-diagram/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 12:08:22 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[ACL]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=631</guid>
		<description><![CDATA[I had some trouble with this rather complicated COM structure called ACTRL_ACCESS. So I post a diagram to show its design. Otherwise it would be a pity to leave it on my private hard drive. The ACTRL_ACCESS structure is used by the interface method IAccessControl::GetAllAccessRights (and others) which is rather hard to implement yourself because [...]]]></description>
			<content:encoded><![CDATA[<p>I had some trouble with this rather complicated COM structure called ACTRL_ACCESS. So I post a diagram to show its design. Otherwise it would be a pity to leave it on my private hard drive.</p>
<p><span id="more-631"></span></p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/ms693447%28VS.85%29.aspx">ACTRL_ACCESS</a> structure is used by the interface method <a href="http://msdn.microsoft.com/en-us/library/ms688536%28VS.85%29.aspx">IAccessControl::GetAllAccessRights</a> (and others) which is rather hard to implement yourself because the structure must be created in a single block of memory that can be freed by CoTaskMemFree.</p>
<p>So here is how it looks like</p>
<div id="attachment_632" class="wp-caption alignnone" style="width: 427px"><a href="http://blog.delphi-jedi.net/wp-content/uploads/2010/02/IAccessControl_GetAllAccessRights-structures.png" rel="lightbox[631]" title="IAccessControl_GetAllAccessRights structures"><img class="size-full wp-image-632 " title="IAccessControl_GetAllAccessRights structures" src="http://blog.delphi-jedi.net/wp-content/uploads/2010/02/IAccessControl_GetAllAccessRights-structures.png" alt="ACTRL_ACCESS design diagram" width="417" height="399" /></a><p class="wp-caption-text">ACTRL_ACCESS design diagram</p></div>
<p>Luckily, JWSCL will provide an implementation of IAccessControl so don&#8217;t worry.</p>
<p><br class="spacer_" /></p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/02/11/actrl_access-diagram/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Case of The Failed Loading of The User Profile</title>
		<link>http://blog.delphi-jedi.net/2009/07/20/the-case-of-the-failed-loading-of-the-user-profile/</link>
		<comments>http://blog.delphi-jedi.net/2009/07/20/the-case-of-the-failed-loading-of-the-user-profile/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 20:52:45 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[Administrator]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[profile]]></category>
		<category><![CDATA[Registry]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=370</guid>
		<description><![CDATA[Some time ago, I was in the situation to set up a new computer with a Windows XP 64 CD. Well it doesn&#8217;t matter that it was 64bit.  However, I always create a separate partitions for Windows XP. And because user profiles tend to get big, I moved a new user to a second partition. [...]]]></description>
			<content:encoded><![CDATA[<p>Some time ago, I was in the situation to set up a new computer with a Windows XP 64 CD. Well it doesn&#8217;t matter that it was 64bit.  However, I always create a separate partitions for Windows XP. And because user profiles tend to get big, I moved a new user to a second partition. (See the Internet how it is done) But as if it wasn&#8217;t enough I thought that I also could move the Administrator profile that easy. Way wrong!</p>
<p><span id="more-370"></span>First of all, copying a loaded user profile isn&#8217;t possible without the BACKUP privilege. You can&#8217;t open already opened files a second time (share deny). The solution is: Either you can use a backup application that runs with the special privilege or you can just use another administrative user (which I did).</p>
<p>There are some keys which have absolute path variables that must be changed, too. But that is a minor problem. The big problem was that Windows could not load the profile of the Administrator. Windows tried to start up the users desktop but then failed with the dialog:  &#8220;Windows failed to load user profile.&#8221;</p>
<p>It got more confusing because every other user in the system didn&#8217;t suffer from this problem. And to top it,  sometimes I could successfully login to the Administrator account.</p>
<h3>Solution</h3>
<p>In such cases the event manager is a good way to find the error source. In my case, it told me that &#8220;NTUSER.DAT&#8221; (this is where Windows stores the current user keys called a <a href="http://msdn.microsoft.com/en-us/library/ms724877%28VS.85%29.aspx">registry hive</a>) was already opened by another process. I really can&#8217;t say why this was the case because it shouldn&#8217;t be the case shortly after a fresh boot up. (Of course, the file was correct, it had no write protection, and security was set accordingly)</p>
<p>In such a case you usually have some ways to fix the problem:</p>
<p>1. Reinstall Windows<br />
Good choice. But too much work &#8212; and who will promise me that it won&#8217;t happen again?</p>
<p>2. Leave Administrator where it was<br />
Also good choice. And I tried it. However my Windows could not handle two profile places somehow and the very same error occured with the old profile location.</p>
<p>3. Live with the situation<br />
Some people do it. I thought about it, too, I have to admit. That&#8217;s because there is a user called root in the system now.</p>
<p>4. Find the bug and ignore how much time it will cost.<br />
Ouch. I don&#8217;t have time, so not a good option.</p>
<p>5.Create a workaround.<br />
YES! That&#8217;s what I did.</p>
<p>So I came up with a practical and fast solution. As I&#8217;ve already written, the user&#8217;s registry hive could not be loaded.<br />
Why? I don&#8217;t know much about it but the registry file was blocked.<br />
Well, I&#8217;ve found out that if the Administrator registry hive was already loaded (HKEY_USERS\S-1-5-21-xxx-500 is visible) the Windows could successfully logon the Administrator. I simulated this situation by manually loading the user&#8217;s profile using the <a href="http://msdn.microsoft.com/en-us/library/bb762281%28VS.85%29.aspx" target="_blank">LoadUserProfile</a> function from Windows API. Well, it always worked!</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span><br />
&nbsp; JwaWindows,<br />
&nbsp; JwsclToken,<br />
&nbsp; jwscltypes;</p>
<p><span class="kw1">var</span><br />
&nbsp; &nbsp;T : TJwSecurityToken;<br />
&nbsp; &nbsp;ProfileInfo : TJwProfileInfo;<br />
<span class="kw1">begin</span><br />
&nbsp; T := TJwSecurityToken.<span class="me1">CreateTokenByProcess</span><span class="br0">&#40;</span><span class="nu0">0</span>, TOKEN_ALL_ACCESS<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; T.<span class="me1">LoadUserProfile</span><span class="br0">&#40;</span>ProfileInfo, <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; T.<span class="me1">Free</span>;<br />
&nbsp; <span class="kw1">end</span>;</div>
<p>The next step was to do it automatically before an Administrator could logon. Of course, I could have created a service which loads the user profile at startup but I wanted to be fast so there is another option called Task Scheduler.<br />
Every Windows startup I let run the code above as a simple task with Administrator credentials (needs password).</p>
<p>I don&#8217;t know whether the Task Scheduler loads the profile (I would guess so). However the problem is that the profile could be unloaded after the process has ended. So the hive would be removed and logon would no more be possible.</p>
<p>Thus the code above just loads the profile but does not unload it. Since profiles are not watched by Windows (at least in XP) the registry hive  stays loaded and a logon attempt will work (T.Free won&#8217;t unload it!).</p>
<h3>JEDI Windows Security Code Library used features</h3>
<ul>
<li><a href="http://jwscldoc.delphi-jedi.net/TJwSecurityToken.html">TJwSecurityToken</a> (class)<a href="http://jwscldoc.delphi-jedi.net/TJwSecurityToken.html"><br />
</a></li>
<li>TJwSecurityToken.<a href="http://jwscldoc.delphi-jedi.net/TJwSecurityToken_LoadUserProfile@TJwProfileInfo@TJwProfileMembers.html" target="_blank">LoadUserProfile</a> (method)</li>
</ul>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2009/07/20/the-case-of-the-failed-loading-of-the-user-profile/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Restrict access to process</title>
		<link>http://blog.delphi-jedi.net/2008/11/08/restrict-access-to-process/</link>
		<comments>http://blog.delphi-jedi.net/2008/11/08/restrict-access-to-process/#comments</comments>
		<pubDate>Sat, 08 Nov 2008 21:58:11 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[DACL]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[Process]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=271</guid>
		<description><![CDATA[The following code is really simple. It restricts access to the current process. In this way no other process can open the process handle and for example terminate this process. uses &#160; JwaWindows, &#160; JwsclSecureObjects, &#160; JwsclDescriptor, &#160; JwsclToken, &#160; JwsclTypes, &#160; JwsclAcl, &#160; JwsclKnownSid; var &#160; SD : TJwSecurityDescriptor; &#160; hProcess : TJwProcessHandle; begin [...]]]></description>
			<content:encoded><![CDATA[<p>The following code is really simple. It restricts access to the current process. In this way no other process can open the process handle and for example terminate this process.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span><br />
&nbsp; JwaWindows,<br />
&nbsp; JwsclSecureObjects,<br />
&nbsp; JwsclDescriptor,<br />
&nbsp; JwsclToken,<br />
&nbsp; JwsclTypes,<br />
&nbsp; JwsclAcl,<br />
&nbsp; JwsclKnownSid;</p>
<p><span class="kw1">var</span><br />
&nbsp; SD : TJwSecurityDescriptor;<br />
&nbsp; hProcess : TJwProcessHandle;<br />
<span class="kw1">begin</span><br />
&nbsp; JwInitWellKnownSIDs;</p>
<p>&nbsp; hProcess := OpenProcess<span class="br0">&#40;</span>READ_CONTROL <span class="kw1">or</span> WRITE_DAC, <span class="kw2">false</span>, GetCurrentProcessId<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">if</span> hProcess &lt;&gt; <span class="nu0">0</span> <span class="kw1">then</span><br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; SD := TJwSecureGeneralObject.<span class="me1">GetSecurityInfo</span><span class="br0">&#40;</span>hProcess,SE_KERNEL_OBJECT, <span class="br0">&#91;</span>siDaclSecurityInformation<span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; &nbsp; SD.<span class="me1">DACL</span>.<span class="me1">Clear</span>;<br />
&nbsp; &nbsp; &nbsp; SD.<span class="me1">DACL</span>.<span class="me1">Add</span><span class="br0">&#40;</span>TJwDiscretionaryAccessControlEntryAllow.<span class="me1">Create</span><span class="br0">&#40;</span><span class="kw2">nil</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, GENERIC_ALL, JwLocalSystemSID<span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; <span class="co1">//allow read access to the current user</span><br />
&nbsp; &nbsp; &nbsp; SD.<span class="me1">DACL</span>.<span class="me1">Add</span><span class="br0">&#40;</span>TJwDiscretionaryAccessControlEntryAllow.<span class="me1">Create</span><span class="br0">&#40;</span><span class="kw2">nil</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, GENERIC_READ, JwSecurityProcessUserSID<span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; TJwSecureGeneralObject.<span class="me1">SetSecurityInfo</span><span class="br0">&#40;</span>hProcess, SE_KERNEL_OBJECT, <span class="br0">&#91;</span>siDaclSecurityInformation<span class="br0">&#93;</span>, SD<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; &nbsp; SD.<span class="me1">Free</span>;<br />
&nbsp; &nbsp; <span class="kw1">end</span>;<br />
&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; CloseHandle<span class="br0">&#40;</span>hProcess<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">end</span>;<br />
<span class="kw1">end</span>;</div>
<p>However there are some problems:</p>
<ol>
<li>This code does not prevent the user from reverting the process DACL to the original state. An owner of the process can always change the DACL even if she is not listed in it. So the code just prevents a beginner from closing the application forcefully.</li>
<li>Any user with the DEBUG privilege can open the process with full access using <em>OpenProcess</em>. The taskmanager uses this way to terminate a process &#8211; if TaskManager is started with administrative rights.</li>
</ol>
<p>The only way to prevent a restricted user from terminating the application is to run the process with a foreign account (e.g. CreateProcessAsUser) and make sure that the user is not listed in the DACL. However if this user gets the DEBUG privilege the game is over.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/11/08/restrict-access-to-process/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Calculating Binary Hashes using TJwFileStreamEx</title>
		<link>http://blog.delphi-jedi.net/2008/06/17/239/</link>
		<comments>http://blog.delphi-jedi.net/2008/06/17/239/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 08:50:37 +0000</pubDate>
		<dc:creator>NeutralGeneral</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[JWSCL Downloads]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[Memory Mapped Files]]></category>
		<category><![CDATA[MMF]]></category>
		<category><![CDATA[Streams]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=239</guid>
		<description><![CDATA[Calculating Binary Hashes using TJwFileStreamEx Why should I use TJwFileStreamEx instead of any other common stream class from the VCL? Well this question is quite easily answered. The first thing is that TJwFileStreamEx is based on Memory Mapped Files (MMF). MMF might be the fastest way to access files on your hard disk. Another good [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-size: small;"><strong>Calculating Binary Hashes using TJwFileStreamEx</strong></span></p>
<p><strong>Why should I use TJwFileStreamEx instead of any other common stream class from the VCL?</strong></p>
<p>Well this question is quite easily answered.</p>
<p>The first thing is that TJwFileStreamEx is based on Memory Mapped Files (MMF). MMF might be the fastest way to access files on your hard disk. Another good reason for using TJwFileStreamEx is its <em>Memory</em> property which is well known from the VCL <strong>TMemoryStream</strong> class. This property will reduce the effort remarkably.</p>
<p><strong>Getting Started</strong></p>
<p>First you have to include following units to your project:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> JwsclTypes, JwsclStreams, JwsclCryptProvider;</div>
<p>The signature of our hashing-function looks like this:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">function</span> GetFileHash<span class="br0">&#40;</span>Algorithm: TJwHashAlgorithm; <span class="kw1">const</span> Filename: <span class="kw4">String</span><span class="br0">&#41;</span> : <span class="kw4">String</span>;</div>
<p>The first parameter is used to specify the Algorithm which is used to hash the file data. The second parameter defines the path to the file which hash you want to compute.</p>
<p>So what do we need to calculate the hash of a file? All we need is an instance of TJwFileStreamEx to open the file and an instance of TJwHash to calculate the hash:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">function</span> GetFileHash<span class="br0">&#40;</span>Algorithm: TJwHashAlgorithm; <span class="kw1">const</span> Filename: <span class="kw4">String</span><span class="br0">&#41;</span> : <span class="kw4">String</span>;<br />
<span class="kw1">var</span><br />
&nbsp; Stream: TJwFileStreamEx;<br />
&nbsp; Hash: TJwHash;<br />
<span class="kw1">begin</span><br />
&nbsp; Stream := TJwFileStreamEx.<span class="me1">Create</span><span class="br0">&#40;</span>Filename,fmOpenRead<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; Hash := TJwHash.<span class="me1">Create</span><span class="br0">&#40;</span>Algorithm<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="co1">// Calculate and return the Hash as a Hex-String</span><br />
&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; Hash.<span class="me1">Free</span>;<br />
&nbsp; &nbsp; Stream.<span class="me1">Free</span>; &nbsp;<br />
&nbsp; <span class="kw1">end</span>;<br />
<span class="kw1">end</span>;</div>
<p>This is the basic framework of our function. To calculate the hash of the file we need 2 methods:</p>
<div class="dean_ch" style="white-space: wrap;">TJwHash.<span class="me1">HashData</span><span class="br0">&#40;</span>Data: <span class="kw4">Pointer</span>; Size: <span class="kw4">Cardinal</span><span class="br0">&#41;</span>;<br />
TJwHash.<span class="me1">RetrieveHash</span><span class="br0">&#40;</span>out Len: <span class="kw4">Cardinal</span><span class="br0">&#41;</span>: <span class="kw4">Pointer</span>;</div>
<p>HashData tells our instance of TJwHash which data is to be hashed and which size this data has. RetrieveHash calculates the Hash and retrieves a pointer to the hash data.</p>
<p>Finally we have to free the Buffer using the class method</p>
<div class="dean_ch" style="white-space: wrap;">TJwHash.<span class="me1">FreeBuffer</span><span class="br0">&#40;</span>Buffer: <span class="kw4">Pointer</span><span class="br0">&#41;</span>;</div>
<p>Now our function looks like this:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">function</span> GetFileHash<span class="br0">&#40;</span>Algorithm: TJwHashAlgorithm; <span class="kw1">const</span> Filename: <span class="kw4">String</span><span class="br0">&#41;</span> : <span class="kw4">String</span>;<br />
<span class="kw1">var</span><br />
&nbsp; Stream: TJwFileStreamEx;<br />
&nbsp; Hash: TJwHash;<br />
&nbsp; HashSize: <span class="kw4">Cardinal</span>;<br />
&nbsp; HashData: <span class="kw4">Pointer</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; Stream := TJwFileStreamEx.<span class="me1">Create</span><span class="br0">&#40;</span>Filename,fmOpenRead<span class="br0">&#41;</span>;<br />
&nbsp; Hash := TJwHash.<span class="me1">Create</span><span class="br0">&#40;</span>Algorithm<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; Hash.<span class="me1">HashData</span><span class="br0">&#40;</span>Stream.<span class="me1">Memory</span>,Stream.<span class="me1">Size</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; HashData := Hash.<span class="me1">RetrieveHash</span><span class="br0">&#40;</span>HashSize<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; TJwHash.<span class="me1">FreeBuffer</span><span class="br0">&#40;</span>HashData<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; Hash.<span class="me1">Free</span>;<br />
&nbsp; &nbsp; Stream.<span class="me1">Free</span>;<br />
&nbsp; <span class="kw1">end</span>;<br />
<span class="kw1">end</span>;</div>
<p>At last we need to convert the binary hash into a hex-string:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">for</span> i:= <span class="nu0">1</span> <span class="kw1">to</span> HashSize <span class="kw1">do</span><br />
<span class="kw1">begin</span><br />
&nbsp; Result := Result + <span class="kw3">IntToHex</span><span class="br0">&#40;</span><span class="kw4">PByte</span><span class="br0">&#40;</span>HashData<span class="br0">&#41;</span>^,<span class="nu0">2</span><span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw3">inc</span><span class="br0">&#40;</span><span class="kw4">PByte</span><span class="br0">&#40;</span>HashData<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;<br />
<span class="kw3">dec</span><span class="br0">&#40;</span><span class="kw4">PByte</span><span class="br0">&#40;</span>HashData<span class="br0">&#41;</span>,HashSize<span class="br0">&#41;</span>; <span class="co1">//neccessary to free HashData</span></div>
<p>Now we&#8217;re done and finally our function looks like this:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">function</span> GetFileHash<span class="br0">&#40;</span>Algorithm: TJwHashAlgorithm; <span class="kw1">const</span> Filename: <span class="kw4">String</span><span class="br0">&#41;</span> : <span class="kw4">String</span>;<br />
<span class="kw1">var</span><br />
&nbsp; Stream: TJwFileStreamEx;<br />
&nbsp; Hash: TJwHash;<br />
&nbsp; HashSize: <span class="kw4">Cardinal</span>;<br />
&nbsp; HashData: <span class="kw4">Pointer</span>;<br />
&nbsp; i: <span class="kw4">Integer</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; Stream := TJwFileStreamEx.<span class="me1">Create</span><span class="br0">&#40;</span>Filename,fmOpenRead<span class="br0">&#41;</span>;<br />
&nbsp; Hash := TJwHash.<span class="me1">Create</span><span class="br0">&#40;</span>Algorithm<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; Hash.<span class="me1">HashData</span><span class="br0">&#40;</span>Stream.<span class="me1">Memory</span>,Stream.<span class="me1">Size</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; HashData := Hash.<span class="me1">RetrieveHash</span><span class="br0">&#40;</span>HashSize<span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; <span class="kw1">for</span> i:= <span class="nu0">1</span> <span class="kw1">to</span> HashSize <span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="kw1">begin</span><br />
&nbsp; &nbsp; &nbsp; Result := Result + <span class="kw3">IntToHex</span><span class="br0">&#40;</span><span class="kw4">PByte</span><span class="br0">&#40;</span>HashData<span class="br0">&#41;</span>^,<span class="nu0">2</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="kw3">inc</span><span class="br0">&#40;</span><span class="kw4">PByte</span><span class="br0">&#40;</span>HashData<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">end</span>;<br />
&nbsp; &nbsp; <span class="kw3">dec</span><span class="br0">&#40;</span><span class="kw4">PByte</span><span class="br0">&#40;</span>HashData<span class="br0">&#41;</span>,HashSize<span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; TJwHash.<span class="me1">FreeBuffer</span><span class="br0">&#40;</span>HashData<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; Hash.<span class="me1">Free</span>;<br />
&nbsp; &nbsp; Stream.<span class="me1">Free</span>;<br />
&nbsp; <span class="kw1">end</span>;<br />
<span class="kw1">end</span>;</div>
<p><strong>How do I use this function?</strong></p>
<div class="dean_ch" style="white-space: wrap;"><span class="co1">// first param can be one of these values:</span><br />
<span class="co1">// haMD2, haMD4, haMD5, haSHA</span><br />
Label1.<span class="me1">Caption</span> := GetFileHash<span class="br0">&#40;</span>haSHA,<span class="st0">&#8216;C:\Progam Files\Program\AFile.ext&#8217;</span><span class="br0">&#41;</span>;</div>
<p><strong>OK, but what is the advantage of TJwFileStreamEx over other Streams?</strong></p>
<p>Well, you don&#8217;t have to load the file into a TMemoryStream and thus the file will not be loaded completely into memory. Furthermore this solution is much faster than a solution using TMemoryStream and similar&#8230;</p>
<h2>Download</h2>
<p><a href="http://blog.delphi-jedi.net/wp-content/uploads/2008/06/jwfilestreamex_demo.zip">Download</a> the source and binaries of this example (260kiB). This includes the new and necessary JWSCL source files. However you need to download the whole package separately.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/06/17/239/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>AutoPointer with JWSCL [Update]</title>
		<link>http://blog.delphi-jedi.net/2008/05/25/autopointer-with-jwscl/</link>
		<comments>http://blog.delphi-jedi.net/2008/05/25/autopointer-with-jwscl/#comments</comments>
		<pubDate>Sun, 25 May 2008 10:00:11 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Downloads]]></category>
		<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[JWSCL]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=126</guid>
		<description><![CDATA[JWSCL provides access to auto pointers or objects. It means that allocated space or objects are automtically destroyed/freed as soon as the auto object runs out of scope. What is a scope? A scope exists as long as the (I say) parent object exists. Parent objects can be: The process. The auto pointer and thus [...]]]></description>
			<content:encoded><![CDATA[<p>JWSCL provides access to auto pointers or objects. It means that allocated space or objects are automtically destroyed/freed as soon as the auto object runs out of scope. What is a scope? A scope exists as long as the (I say) parent object exists. Parent objects can be:</p>
<ol>
<li>The process. The auto pointer and thus the object exist as long as the process runs. The object will be destroyed when the process is destroyed.</li>
<li>A class or record. The auto pointer exists as long as the class instance exists. If the instance is freed the managed auto pointer object will be freed as well.</li>
</ol>
<p>What is not a parent object?</p>
<ol>
<li>begin end. In contrast to C++, a begin/end construct does not allow to create a variable scope. You have to create a new function do achieve the same effect.</li>
<li>A pointer to an object. Auto pointer to any object (class, record, variable) will not be automatically destroyed. You have to free the memory manually (Dispose, FreeMem) to let the auto pointer take effect.</li>
</ol>
<p>The current release only allows to create or wrap objects. It is done by the methods of <a href="http://jwscldoc.delphi-jedi.net/JwsclComUtils.TJwAutoPointer.html#%40Methods">TJwAutoPointer</a>.</p>
<p>The following sample shows how to avoid to manually call free. It uses the Wrap method of TJwAutoPointer to activate the managed pointer mechanism. There is no method to undo this call.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">procedure</span> X;<br />
<span class="kw1">var</span><br />
&nbsp; ManagedObject : TJwSecurityID;<br />
&nbsp; AutoPtr : IJwAutoPointer;<br />
<span class="kw1">begin</span><br />
&nbsp; ManagedObject := TJwSecurityID.<span class="me1">Create</span><span class="br0">&#40;</span>&#8230;<span class="br0">&#41;</span>;<br />
&nbsp; AutoPtr := TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>ManagedObject<span class="br0">&#41;</span>;<br />
&#8230;<br />
<span class="co1">//no need to free ManagedObject</span><br />
<span class="kw1">end</span>;</div>
<p>The advantage of the auto pointer approach is that we do not need to call Free for every possible exit. Even exceptions cannot avoid that the managed object is destroyed.<br />
The next sample demonstrates this fact.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">procedure</span> X;<br />
<span class="kw1">var</span><br />
&nbsp; ManagedObject : TJwSecurityID;<br />
&nbsp; AutoPtr : IJwAutoPointer;<br />
<span class="kw1">begin</span><br />
&nbsp; ManagedObject := TJwSecurityID.<span class="me1">Create</span><span class="br0">&#40;</span>&#8230;<span class="br0">&#41;</span>;<br />
&nbsp; AutoPtr := TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>ManagedObject<span class="br0">&#41;</span>;</p>
<p>&nbsp; <span class="kw1">if</span> DoExit <span class="kw1">then</span><br />
&nbsp; &nbsp;<span class="kw3">exit</span>;</p>
<p>&nbsp; <span class="kw1">if</span> Error <span class="kw1">then</span><br />
&nbsp; &nbsp;<span class="kw1">raise</span> Exception.<span class="me1">Create</span><span class="br0">&#40;</span>&#8230;<span class="br0">&#41;</span>;<br />
&nbsp; &#8230;<br />
&nbsp; <span class="co1">//no need to free ManagedObject</span><br />
<span class="kw1">end</span>;</div>
<p>The same way can be used to add the IJwAutoPointer variable into classes and records.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span><br />
&nbsp; SysUtils,<br />
&nbsp; JwsclComUtils;<br />
<span class="kw1">type</span><br />
&nbsp; TMyClass = <span class="kw1">class</span><br />
&nbsp; <span class="kw1">public</span><br />
&nbsp; &nbsp; N : <span class="kw4">String</span>;<br />
&nbsp; &nbsp; x : IJwAutoPointer;<br />
&nbsp; &nbsp; <span class="kw1">constructor</span> Create<span class="br0">&#40;</span>Name : <span class="kw4">String</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">destructor</span> Destroy; <span class="kw1">override</span>;<br />
&nbsp; <span class="kw1">end</span>;</p>
<p>TMyRecord = <span class="kw1">record</span><br />
&nbsp; x : IJwAutoPointer;<br />
<span class="kw1">end</span>;</p>
<p><span class="kw1">constructor</span> TMyClass.<span class="me1">Create</span><span class="br0">&#40;</span>Name: <span class="kw4">String</span><span class="br0">&#41;</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="kw1">inherited</span> Create;<br />
&nbsp; <span class="kw3">Writeln</span><span class="br0">&#40;</span><span class="st0">&#8216;Create :&#8217;</span>,Name<span class="br0">&#41;</span>;<br />
&nbsp; N := Name;<br />
<span class="kw1">end</span>;</p>
<p><span class="kw1">destructor</span> TMyClass.<span class="me1">Destroy</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="kw3">Writeln</span><span class="br0">&#40;</span><span class="st0">&#8216;DesTMyRecordoy: &#8216;</span>,N<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">inherited</span>;<br />
<span class="kw1">end</span>;</p>
<p><span class="kw1">procedure</span> X;<br />
<span class="kw1">var</span> Y,Z : TMyClass;<br />
<span class="kw1">begin</span><br />
&nbsp; Y := TMyClass.<span class="me1">Create</span><span class="br0">&#40;</span><span class="st0">&#8217;1&#8242;</span><span class="br0">&#41;</span>;<br />
&nbsp; Z := TMyClass.<span class="me1">Create</span><span class="br0">&#40;</span><span class="st0">&#8217;2&#8242;</span><span class="br0">&#41;</span>;<br />
&nbsp; Y.<span class="me1">x</span> := TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>Z<span class="br0">&#41;</span>;</p>
<p>&nbsp; Y.<span class="me1">Free</span>;<br />
<span class="kw1">end</span>;</p>
<p><span class="kw1">procedure</span> Y<span class="br0">&#40;</span>UseDispose : <span class="kw4">Boolean</span><span class="br0">&#41;</span>;<br />
<span class="kw1">var</span><br />
&nbsp; L : TMyRecord;<br />
&nbsp; pL : ^TMyRecord;<br />
&nbsp; Y : TMyClass;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="kw3">new</span><span class="br0">&#40;</span>pL<span class="br0">&#41;</span>;<br />
&nbsp; Y := TMyClass.<span class="me1">Create</span><span class="br0">&#40;</span><span class="st0">&#8217;1&#8242;</span><span class="br0">&#41;</span>;<br />
&nbsp; PL.<span class="me1">x</span> := TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>Y<span class="br0">&#41;</span>;</p>
<p>&nbsp; <span class="kw3">writeln</span>;<br />
&nbsp; <span class="kw1">if</span> UseDispose &nbsp;<span class="kw1">then</span><br />
&nbsp; &nbsp;<span class="kw3">dispose</span><span class="br0">&#40;</span>PL<span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</div>
<p>A call to X returns:</p>
<p style="padding-left: 30px;">Create :1<br />
Create :2<br />
Destroy: 1<br />
Destroy: 2</p>
<p>As you can see, the managed object (Name : &#8220;2&#8243;) is shortly destroyed after the parent object is destroyed. You should know about this fact, because accessing the parent object will fail (if you are luck) in an exception.</p>
<p>A call to Y(false) returns</p>
<p style="padding-left: 30px;">Create :1</p>
<p>A call to Y(true) returns</p>
<p style="padding-left: 30px;">Create :1<br />
Destroy: 1</p>
<p>The next release of <strong>JWSCL</strong> will bring support for pointers created by <strong>New</strong> and <strong>GetMem</strong> as well as <strong>LocalAlloc</strong>. It will also implement thread safe locking mechanisms.</p>
<h2>[Update]</h2>
<p>There is no need to save the COM object if you want to keep the object only alive in a single function.<br />
Just wrap it.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">procedure</span> X;<br />
<span class="kw1">var</span> Y,Z : TMyClass;<br />
<span class="kw1">begin</span><br />
&nbsp; Y := TMyClass.<span class="me1">Create</span><span class="br0">&#40;</span><span class="st0">&#8217;1&#8242;</span><span class="br0">&#41;</span>;<br />
&nbsp; TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>Y<span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</div>
<p>You even can wrap it several times. All wrapped up instances will be freed, regardeless of the variable&#8217;s name.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">procedure</span> X;<br />
<span class="kw1">var</span> Y,Z : TMyClass;<br />
<span class="kw1">begin</span><br />
&nbsp; Y := TMyClass.<span class="me1">Create</span><span class="br0">&#40;</span><span class="st0">&#8217;1&#8242;</span><span class="br0">&#41;</span>;<br />
&nbsp; TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>Y<span class="br0">&#41;</span>;</p>
<p>&nbsp; Y := TMyClass.<span class="me1">Create</span><span class="br0">&#40;</span><span class="st0">&#8217;2&#8242;</span><span class="br0">&#41;</span>;<br />
&nbsp; TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>Y<span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</div>
<p>Of course you can&#8217;t access the first object anymore. But sometimes it comes quite handy.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/05/25/autopointer-with-jwscl/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Setting the SessionID for a new process</title>
		<link>http://blog.delphi-jedi.net/2008/05/23/setting-the-sessionid-for-a-new-process/</link>
		<comments>http://blog.delphi-jedi.net/2008/05/23/setting-the-sessionid-for-a-new-process/#comments</comments>
		<pubDate>Fri, 23 May 2008 09:26:01 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[Token]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=224</guid>
		<description><![CDATA[This simple example shows how you can change the target session of a new process. uses &#160; JwaWindows, &#160; JwsclToken, &#160; JwsclComUtils; var &#160; &#160;NewToken, &#160; &#160;UserToken : TJwSecurityToken; &#160; &#160;S : TStartupInfo; &#160; &#160;P : TProcessInformation; begin &#160; UserToken := TJwSecurityToken.CreateWTSQueryUserTokenEx&#40;nil, 1&#41;; //for example: here SessionID = 1 &#160; TJwAutoPointer.Wrap&#40;UserToken&#41;; //automatic destroy &#160; NewToken [...]]]></description>
			<content:encoded><![CDATA[<p>This simple example shows how you can change the target session of a new process.</p>
<p><span id="more-224"></span></p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span><br />
&nbsp; JwaWindows,<br />
&nbsp; JwsclToken,<br />
&nbsp; JwsclComUtils; </p>
<p><span class="kw1">var</span><br />
&nbsp; &nbsp;NewToken,<br />
&nbsp; &nbsp;UserToken : TJwSecurityToken;</p>
<p>&nbsp; &nbsp;S : TStartupInfo;<br />
&nbsp; &nbsp;P : TProcessInformation;<br />
<span class="kw1">begin</span><br />
&nbsp; UserToken := TJwSecurityToken.<span class="me1">CreateWTSQueryUserTokenEx</span><span class="br0">&#40;</span><span class="kw2">nil</span>, <span class="nu0">1</span><span class="br0">&#41;</span>; <span class="co1">//for example: here SessionID = 1 </span><br />
&nbsp; TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>UserToken<span class="br0">&#41;</span>; <span class="co1">//automatic destroy </span></p>
<p>&nbsp; NewToken := TJwSecurityToken.<span class="me1">CreateDuplicateExistingToken</span><span class="br0">&#40;</span>UserToken.<span class="me1">TokenHandle</span>, MAXIMUM_ALLOWED<span class="br0">&#41;</span>;<br />
&nbsp; TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>NewToken<span class="br0">&#41;</span>; &nbsp;</p>
<p>&nbsp; <span class="co1">//needs TCB privilege -&gt; Service</span><br />
&nbsp; JwEnablePrivilege<span class="br0">&#40;</span>SE_TCB_NAME, pst_Enable<span class="br0">&#41;</span>;<br />
&nbsp; NewToken.<span class="me1">TokenSessionId</span> := <span class="nu0">2</span>; <span class="co1">//e.g. set to session 2 &#8211; of course it must exist</span><br />
&nbsp; <br />
&nbsp; ZeroMemory<span class="br0">&#40;</span>@S, <span class="kw3">Sizeof</span><span class="br0">&#40;</span>S<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; S.<span class="me1">cb</span> := <span class="kw3">sizeof</span><span class="br0">&#40;</span>S<span class="br0">&#41;</span>;<br />
&nbsp; <span class="co1">//examplary, but working CPAU call &#8211; adapt for your need</span><br />
&nbsp; CreateProcessAsUser<span class="br0">&#40;</span>NewToken.<span class="me1">TokenHandle</span>,<span class="st0">&#8216;C:\Windows\system32\cmd.exe&#8217;</span>,<span class="kw2">nil</span>,<span class="kw2">nil</span>,<span class="kw2">nil</span>,<span class="kw2">false</span>, <span class="nu0">0</span>, <span class="kw2">nil</span>, <span class="kw2">nil</span>, S,P<span class="br0">&#41;</span>;</div>
<p>All the source is doing is to get a user&#8217;s token by calling CreateWTSQueryUserToken and then duplicate so it will become possible to change the Token SessionID. The session ID is changed by setting the property TokenSessionID which is only possible with the TCB privilege (we need it, but it needn&#8217;t to be active).<br />
 You can do the CreateProcess part a little better if you read this: “<a href="../2008/04/11/createprocess-in-full-glory/">CreateProcess in full glory</a>“.</p>
<p>Did you know?<br />
 1. You can test this example in your own Delphi environment <a href="http://blog.delphi-jedi.net/2008/05/07/debugging-services-an-easy-way/">without writing a service</a> first.</p>
<p>2. It is not possible to change the session ID of a running process.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/05/23/setting-the-sessionid-for-a-new-process/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
