<?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>Fri, 05 Mar 2010 18:24:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Site Recommendation: Terminal Session and Desktops</title>
		<link>http://blog.delphi-jedi.net/2010/03/05/site-recommendation-terminal-session-and-desktops/</link>
		<comments>http://blog.delphi-jedi.net/2010/03/05/site-recommendation-terminal-session-and-desktops/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 18:24:46 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[Recommendation]]></category>
		<category><![CDATA[Russinovich]]></category>
		<category><![CDATA[Session]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=674</guid>
		<description><![CDATA[Many Windows Programmers still have trouble when it comes to sessions, window stations and desktops. They frequently get mixed up and we can see a lot of question on the Internet about e.g. how to spawn processes in all logged-on user desktops (rather than sessions).  Hence, I have listed some articles that you can read [...]]]></description>
			<content:encoded><![CDATA[<p>Many Windows Programmers still have trouble when it comes to sessions, window stations and desktops. They frequently get mixed up and we can see a lot of question on the Internet about e.g. how to spawn processes in all logged-on user desktops (rather than sessions).  Hence, I have listed some articles that you can read to get a better understanding of such things like a Terminal Sessions.</p>
<p><span id="more-674"></span></p>
<p>To understand the concept of Window Sessions, Stations and Desktop it is not necessary to read all articles to the end. I think the beginning is just fine.</p>
<ul>
<li><strong>Pushing the Limits of Windows: USER and GDI Objects</strong><br />
 Mark Russinovich writes about USER and GDI objects but he also gives a basic introduction how sessions, windowstations and desktops are related.  </p>
<ul>
<li><a href="http://blogs.technet.com/markrussinovich/archive/2010/02/24/3315174.aspx" target="_blank">Part 1 </a></li>
<li>Part 2  (still writing)</li>
</ul>
</li>
<li><strong>Desktop Heap Overview</strong><br />
 The guys from<strong> Advanced Windows Debugging and Troubleshooting</strong> explain how it is possible that a desktop can run out of heap. It is a quite technical article but it gives a nice insight into some of the Windows internals.</p>
<ul>
<li><a href="http://blogs.msdn.com/ntdebugging/archive/2007/01/04/desktop-heap-overview.aspx" target="_blank">Part1</a></li>
<li><a href="http://blogs.msdn.com/ntdebugging/archive/2007/07/05/desktop-heap-part-2.aspx" target="_blank">Part2</a></li>
</ul>
</li>
</ul>
<p>I often prefer such blog articles to MSDN articles because blog articles are much more fun to read.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/03/05/site-recommendation-terminal-session-and-desktops/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JWSCL and FreeAndNil Second Attempt</title>
		<link>http://blog.delphi-jedi.net/2010/02/25/jwscl-and-freeandnil-second-attempt/</link>
		<comments>http://blog.delphi-jedi.net/2010/02/25/jwscl-and-freeandnil-second-attempt/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 19:48:08 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[JWA]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=665</guid>
		<description><![CDATA[In my last article &#8220;Jwscl and FreeAndNil&#8221; there were some great comments on the source design. Oliver told me to use a guarded memory page so the memory is always invalid. With his information I wrote a source code that creates a pointer which always triggers an access violation.
Unfortunately, Access Violations are rather common and [...]]]></description>
			<content:encoded><![CDATA[<p>In my last article &#8220;<a href="http://blog.delphi-jedi.net/2010/02/25/jwscl-and-freeandnil/" target="_blank">Jwscl and FreeAndNil</a>&#8221; there were some great comments on the source design. Oliver told me to use a guarded memory page so the memory is always invalid. With his information I wrote a source code that creates a pointer which always triggers an access violation.</p>
<p><span id="more-665"></span>Unfortunately, Access Violations are rather common and thus nobody can tell why it happens at a first glance. So I added an exception handler that maps this special access violation to a separate exception class (I called it EJwsclAccessedGuardPointerException).</p>
<p><pre><pre class="brush:delphi">uses
&nbsp;&nbsp;ExceptionLog,
&nbsp;&nbsp;//JwaWindows, //or
&nbsp;&nbsp;JwaWinBase, JwaWinNT, JwaNtStatus,
&nbsp;&nbsp;SysUtils;

type
&nbsp;&nbsp;EJwsclAccessedGuardPointerException = class(Exception)
&nbsp;&nbsp;public
&nbsp;&nbsp;&nbsp;&nbsp;ExceptionRecord: PExceptionRecord;
&nbsp;&nbsp;end;

resourcestring
&nbsp;&nbsp;SGuardPageException = &#039;It was tried to access a guarded pointer. This &#039;+
&nbsp;&nbsp; &#039;pointer was freed previously and is now accessed without initialization. &#039;+
&nbsp;&nbsp; &#039;JWSCL may guard its class members in this way. You should check for &#039;+
&nbsp;&nbsp; &#039; accesses to e.g. class members which instance was freed.&#039;#13#10+
&nbsp;&nbsp; &#039;Exception was raised at this address: $%p&#039;;

var
&nbsp;&nbsp;GuardPtr : Pointer;
&nbsp;&nbsp;OldExcpObj : function (P: PExceptionRecord): Exception;
&nbsp;&nbsp;OldExitProc : procedure;

procedure MyExitProcessProc;
begin
&nbsp;&nbsp;VirtualFree(GuardPtr, 0, MEM_RELEASE);

&nbsp;&nbsp;if @OldExitProc &amp;lt;&amp;gt; nil then
&nbsp;&nbsp;&nbsp;&nbsp;OldExitProc;
end;

function MyGetExceptionObject(P: PExceptionRecord): Exception;
var ErrorCode : Integer;
begin
&nbsp;&nbsp;if (P.ExceptionCode = STATUS_ACCESS_VIOLATION) and
&nbsp;&nbsp;&nbsp;&nbsp;(P.ExceptObject = GuardPtr) then
&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;result := EJwsclAccessedGuardPointerException.CreateFmt(SGuardPageException,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[P.ExceptionAddress]);
&nbsp;&nbsp;&nbsp;&nbsp;EJwsclAccessedGuardPointerException(Result).ExceptionRecord := P;
&nbsp;&nbsp;end
&nbsp;&nbsp;else
&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;result := OldExcpObj(P);
&nbsp;&nbsp;end;
end;

var
&nbsp;&nbsp;T : TObject;
&nbsp;&nbsp;SysInfo : TSystemInfo;
begin
&nbsp;&nbsp;OldExcpObj := ExceptObjProc;
&nbsp;&nbsp;ExceptObjProc := @MyGetExceptionObject;

&nbsp;&nbsp;OldExitProc := ExitProcessProc;
&nbsp;&nbsp;ExitProcessProc := MyExitProcessProc;

&nbsp;&nbsp;//On 32Bit OS call
&nbsp;&nbsp;//GetSystemInfo(@SysInfo);
&nbsp;&nbsp;//On WOW64Bit OS call (use IsWow64Process)
&nbsp;&nbsp;GetNativeSystemInfo(@SysInfo);

&nbsp;&nbsp;GuardPtr := VirtualAlloc(
&nbsp;&nbsp;&nbsp;&nbsp;Pointer($BADC0DE),//&nbsp;&nbsp;__in_opt&nbsp;&nbsp;LPVOID lpAddress,
&nbsp;&nbsp;&nbsp;&nbsp;SysInfo.dwPageSize,//&nbsp;&nbsp;__in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SIZE_T dwSize,
&nbsp;&nbsp;&nbsp;&nbsp;MEM_RESERVE,//&nbsp;&nbsp;__in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD flAllocationType,
&nbsp;&nbsp;&nbsp;&nbsp;PAGE_NOACCESS//&nbsp;&nbsp;__in&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD flProtect
&nbsp;&nbsp;);
&nbsp;&nbsp;if GuardPtr = nil then
&nbsp;&nbsp;&nbsp;&nbsp;RaiseLastOSError;

&nbsp;&nbsp;T := TObject(Pointer(GuardPtr));
&nbsp;&nbsp;T.Free;
end.
</pre></pre></p>
<p>Since the object has this guard pointer value (which may be dynamic) a call to Free (or Destroy) will fail with the exception EJwsclAccessedGuardPointerException. Be aware that there is no actual memory allocated. It is all about virtual memory.</p>
<p>The MyExitProcessProc is called right before the process exits. There is another exit handler called ExitProc that is called before the units are finalized. So I&#8217;m stuck with ExitProcessProc which is fine though.</p>
<p>I must say that I like this approach since it seems to be safer than just using a nearly arbitrary magic value. The value is still there so you can see it as an invalid memory address in a debugger. However, Assigned or similar workarounds will not work because the memory location can vary.<br />
 And of course the exception message clearly states what happened here.  There could added more information like stack trace but that I leave to you (or the JCL).</p>
<p>Be aware that there still might be errors. This code is hot.  <img src='http://blog.delphi-jedi.net/wp-includes/images/smilies/icon_cool.gif' alt='8-)' class='wp-smiley' /> </p>
<p>What is your opinion?<br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/02/25/jwscl-and-freeandnil-second-attempt/feed/</wfw:commentRss>
		<slash:comments>8</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>
]]></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>JWSCL Features Overview</title>
		<link>http://blog.delphi-jedi.net/2010/02/22/jwscl-features-overview/</link>
		<comments>http://blog.delphi-jedi.net/2010/02/22/jwscl-features-overview/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 12:43:46 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JWSCL Downloads]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=652</guid>
		<description><![CDATA[I had some free time that I used to put together all the features JWSCL provides currently. There are some more features that are implemented by other tool classes or functions that I left out in favor of a good overview. A complete overview of all classes, methods and more gives you the documentation at [...]]]></description>
			<content:encoded><![CDATA[<p>I had some free time that I used to put together all the features JWSCL provides currently. There are some more features that are implemented by other tool classes or functions that I left out in favor of a good overview. A complete overview of all classes, methods and more gives you the documentation at <a href="http://jwscldoc.delphi-jedi.net." target="_blank">http://jwscldoc.delphi-jedi.net</a>.</p>
<p>So here are the feautures (You can look up the class names on the documentation page):</p>
<p><span id="more-652"></span></p>
<ul>
<li> Windows Token management (TJwSecurityToken)
<ul>
<li>Impersonation</li>
<li>Supports LogonUser, LsaLogonUser </li>
<li>Lots more</li>
</ul>
</li>
<li>Full support of Security ID (SID) (TJwSecurityID, TJwSecurityIDList)
<ul>
<li>Also well known security IDs like Everyone (JwsclKnownSid.pas) are stored as simple to use variables.</li>
</ul>
</li>
<li>Full support of Access Control Lists (also CALLBACK_ACE and OBJECT_ACE)
<ul>
<li>DACL, SACL</li>
</ul>
</li>
<li>Full support of Security Descriptor (SECURITY_DESCRIPTOR) (TJwSecurityDescriptor)
<ul>
<li>DACL, SACL, Owner, Group</li>
<li>Implements a simple to use Security Descriptor (TJwSimpleDescriptor)</li>
</ul>
</li>
<li>Security Rights Mapping; Maps Generic Rights to specific ones (JwsclMapping.pas)
<ul>
<li>Conversion of Security Rights (DWORD) to Human Readable names (JwFormatAccessRights)</li>
</ul>
</li>
<li>Privileges (TJwPrivilege, TJwPrivilegeSet, JwsclPrivileges.pas)</li>
<li>Windowstation and Desktops (TJwSecurityWindowStation, TJwSecurityDesktop)</li>
<li>Local Security Authority Logon Sessions (TJwLsaLogonSession)</li>
<li>Security of Windows objects; files, registry, handles (TJwSecureFileObject, TJwSecureFileObject, TJwSecureGeneralObject)
<ul>
<li>Support of Access Checking (AccessCheck)</li>
<li>Supports Inheritance (by default only files and registry)</li>
</ul>
</li>
<li>Support of MS AuthZ API; Client Side Access Checks for custom Resources (JwsclAuthCtx.pas) </li>
<li>Credentials GUI API (TJwCredentialsPrompt)</li>
<li>MS Encryption and Protection API (TJwEncryptionApi,  TJwEncryptMemory, TJwRandomDataGenerator)</li>
<li>Windows Version Detection on remote or local client (TJwFileVersion, TJwServerInfo, TJwWindowsVersion) Security Descriptor GUI (TJwSecurityDescriptorDialog)</li>
<li>Terminal Sessions (TJwTerminalServer)
<ul>
<li>Server Management</li>
<li>Sessions Management</li>
<li>Processes Management</li>
</ul>
</li>
<li>Vista Elevation (JwShellExecute, JwElevateProcess, JwsclElevation.pas)
<ul>
<li>Supports <a title="German page only" href="http://kay-bruns.de/wp/software/surun/" target="_blank">SuRun</a> (<a title="Auto Translation" href="http://translate.google.com/translate?u=http%3A%2F%2Fkay-bruns.de%2Fwp%2Fsoftware%2Fsurun%2F&amp;langpair=de%7Cen&amp;hl=de&amp;safe=active&amp;ie=UTF-8&amp;oe=UTF-8&amp;prev=%2Flanguage_tools" target="_blank">English version</a>) (JwElevateProcess, JwCheckSuRunStatus)</li>
</ul>
</li>
<li>Vista Integrity Level (Built in)</li>
<li>Firewall Administration (TJwsclFirewall)</li>
<li>Builtin basic Sma rtpointer Support (TJwAutoLock)</li>
<li>Job Object support (TJwJobObject) even with several sessions (TJwJobObjectSessionList)</li>
<li>Process Handling that encapsulates support for different Windows Versions and bugs in API (functions JwCreateProcessAsAdminUser, JwCreateProcessInSession, JwGetProcessSessionID, JwGetTokenFromProcess, JwProcessIdToSessionId) </li>
<li>Support Memory Mapped Objects (TJwFileStreamEx, TJwIPCStream, TJwVirtualStream)</li>
<li>Extended Thread Support lile naming threads and WaitWithTimeOut (TJwThread)</li>
<li>Hashing Support (TJwHash) 
<ul>
<li>For JWSCL classes (JwObjectHash)</li>
<li>For files (JwCreateFileHash, JwCompareFileHash, JwDataHash, JwIntegerHash) in combination with fast Memory Mapping.</li>
</ul>
</li>
<li>DCOM support for Client and Server (currently only developer branch); CoInitializeSecurity (TJwComProcessSecurity), Authentication, Impersonation, Proxy Security Blanket (TJwComClientSecurity, TJwComServerSecurity), Access Control (TJwServerAccessControl), DCOM Configuration (TJwComRegistrySecurity) of Global Configs and Class Security.</li>
<li>Easy to use WinAPI (Msg)WaitForMultipleObjects functions (JwMsgWaitForMultipleObjects, JwMsgWaitForMultipleObjects)</li>
<li>Multi Language Support of Resource Files (LoadLocalizedString)</li>
<li>Ansi- &amp; Unicode due to own Delphi compatible String type TJwString (JwsclAnsiUniCode.pas)</li>
<li>Mapping of Windows Constants to Delphi enumeration (TJwEnumMap)</li>
<li>All errors are reported by exceptions using a derived class from EJwsclSecurityException. (JwsclExceptions.pas)</li>
<li> Supports Bugreports with Eurekalog (JwsclEurekaLogUtils.pas)</li>
<li>JWSCL is based on OOP </li>
</ul>
<p>To come</p>
<ul>
<li> Active Directory Support</li>
<li>User Account Management</li>
</ul>
<p>Current version is <a href="http://blog.delphi-jedi.net/2009/09/23/releases-for-delphi-2010/">0.9.3 Download.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/02/22/jwscl-features-overview/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Reminder to You</title>
		<link>http://blog.delphi-jedi.net/2010/02/15/reminder-to-you/</link>
		<comments>http://blog.delphi-jedi.net/2010/02/15/reminder-to-you/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 18:28:13 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=640</guid>
		<description><![CDATA[I had some trouble writing these lines because usually I do not want to publish criticism. But Oliver told me that it would be a good idea and I don&#8217;t want to disagree   .
Valid for all open source projects, also the JEDI API&#38;WSCL projects heavily depend on their users. This is not a [...]]]></description>
			<content:encoded><![CDATA[<p>I had some trouble writing these lines because usually I do not want to publish criticism. But <a href="http://blog.assarbad.net/" target="_blank">Oliver</a> told me that it would be a good idea and I don&#8217;t want to disagree <img src='http://blog.delphi-jedi.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p><span id="more-640"></span><span style="font-size: large;">Valid for all open source projects</span>, also the JEDI API&amp;WSCL projects heavily depend on their users. This is not a company where people work all day to make a  great project. I and other members of JEDI use our spare time after real work to bring forward projects such as JEDI.</p>
<p><span style="font-size: large;">Unfortunately, time has changed </span>and less and less people want to provide their skills and manpower in projects like JEDI&#8230;and I am not talking about JEDI API exclusively. That is a pity because we will not provide you with source code forever. Instead the process will come to a halt and we will see more and more questions in newsgroup asking why the project doesn&#8217;t work anymore in Delphi 2020 (or similar).</p>
<p><span style="font-size: large;">I don&#8217;t get it.</span> There are many new API functions in Vista and Windows 7. And I see a lot of people writing conversions from C to Delphi so they can use the new functionality. But instead of donating these sources to JEDI API they post it to their local forum or use it in their project as an internal unit. Usually, I come along and ask these people if they want to donate their source to JEDI API. And the chat goes like this:</p>
<p><em>Christian: &#8220;Hey, I am from JEDI API. Maybe you heard from us. It would be great if your conversion could be integrated into JEDI. Do you agree?&#8221;</em></p>
<p><em>X: &#8220;Yeah, I&#8217;m using your projects a lot. And of course, I would like to see my source integrated into JEDI.&#8221;</em></p>
<p><em>C: &#8220;Well, I need your source code to be converted to some standards we use. I will send you more information about this easy process. If you have further question just ask.&#8221;</em></p>
<p><em>X: &#8220;Eh? Sorry, but I don&#8217;t have time to put more effort into this. Can&#8217;t you just do it yourself?&#8221;</em></p>
<p>Let me answer: <em>Well, If we could do it ourselves we would already have done it. </em>But that means that we would need to give up our jobs and private life to convert over 20.000 functions, interfaces and types only for this project.</p>
<p>Did you know that there is a <a href="http://jedi-apilib.svn.sourceforge.net/viewvc/jedi-apilib/jwapi/trunk/Win32API/_JwaTemplate.pas?revision=857&amp;view=markup" target="_blank">template</a> that shows you how to create a JEDI API file?</p>
<p>Also it often happens that I don&#8217;t hear anything from them. Therefore these conversions never get integrated because I need an explicit agreement.</p>
<p><span style="font-size: large;">On the other hand</span> there are many people who like just to use the source code in their own project because it makes it easier to write good programs. <br />
 May I ask what <span style="text-decoration: underline;">you</span> did to keep alive the project that you gained from?  I have to say from experience that the donations in source and money (in relation to current software prices) are that rare that zero (0) would describe it best. Luckily, this is not entirely true but it is very close to the truth.</p>
<p><span style="font-size: large;">Fortunately, there are a lot of companies</span> which are <strong>generous</strong> and allow us to use their products for free. You can find the list  in the sponsors section of this blog. With a monetary donation of nearly zero we could never use their products. I cannot stop saying: &#8220;<strong>Thank you!</strong>&#8220;</p>
<p><span style="font-size: large;">Also </span>let me use this article to thank all the people who helped or are still helping in these projects. I want to thank them again and again and again! And let me thank the donators again (I wrote them a mail).</p>
<p>&#8211;</p>
<p>Christian</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/02/15/reminder-to-you/feed/</wfw:commentRss>
		<slash:comments>24</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 the [...]]]></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"><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>
]]></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>Programming Habits</title>
		<link>http://blog.delphi-jedi.net/2010/01/14/programming-habits/</link>
		<comments>http://blog.delphi-jedi.net/2010/01/14/programming-habits/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 16:45:29 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=612</guid>
		<description><![CDATA[I&#8217;m writing this article because I want to share programming habits with you. What habit did prove to be a good one for you? Share yours then, please. 
I always add &#8220;RaiseLastOsError&#8221; to every Windows API call.
if not ImpersonateLoggedOnUser(token) then
&#160;&#160;RaiseLastOsError;

In this way you don&#8217;t miss any failed call and wonder what is happening (I can [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m writing this article because I want to share programming habits with you. What habit did prove to be a good one for you? Share yours then, please. <span id="more-612"></span></p>
<h3>I always add &#8220;RaiseLastOsError&#8221; to every Windows API call.</h3>
<p><pre><pre class="brush:delphi">if not ImpersonateLoggedOnUser(token) then
&nbsp;&nbsp;RaiseLastOsError;
</pre></pre></p>
<p>In this way you don&#8217;t miss any failed call and wonder what is happening (I can recall a lot of forum threads that ask about this). <br />
 RaiseLastOsError generates an EOSError exception that contains the error number and text in its message. It also stores the GetLastError value in its property ErrorCode.</p>
<p>One more good thing is that a caller of the function, where this code is implemented, cannot ignore an error value. The API function ImpersonateLoggedOnUser is very problematic because if it fails all subsequent calls are made on the security token of the process instead of the thread. So a client could access more things than usual. So if we had a function that implements the example</p>
<p><pre><pre class="brush:delphi">function MyImpersonateUserToken(UserName : String; out UserData : PUserData) : Boolean;
begin
&nbsp;&nbsp;//get user token here
&nbsp;&nbsp;//get user information from token here and store it into UserData

&nbsp;&nbsp;result := ImpersonateLoggedOnUser(token);
</pre></pre></p>
<p>As you can see a caller can just do the following</p>
<p><pre><pre class="brush:delphi">MyImpersonateUserToken(UserName, UserData);
If UserData.Groups.IsMemberOf(&#039;Administrators&#039;) then
</pre></pre></p>
<p>Be aware that the example is only fictional. However I have seen many production codes that call WinAPI without error checking. The WinAPI usually (and the code above definitely) does not touch any of the output parameters if they fail. So you probably get an Access Violation (best case) or it works randomly (worst case). See that UserData is not initialized here.   But what about this one:</p>
<p><pre><pre class="brush:delphi">procedure MyImpersonateUserToken(UserName : String; out UserData : PUserData);
begin
&nbsp;&nbsp;//get user token here
&nbsp;&nbsp;if not GetUserToken then
&nbsp;&nbsp;&nbsp;&nbsp;raiseLastOsError;
&nbsp;&nbsp;//get user information from token here and store it into UserData
&nbsp;&nbsp;if not GetTokenInformation then
&nbsp;&nbsp;&nbsp;&nbsp;raiseLastOsError; 

&nbsp;&nbsp;if not ImpersonateLoggedOnUser(token) then
&nbsp;&nbsp;&nbsp;&nbsp;raiseLastOsError;
</pre></pre></p>
<p>You see that the function is really a procedure now that throws exceptions in case of failure. In this way the code following the function call MyImpersonateUserToken isn&#8217;t executed at all. Instead, we need to wrap an exception trap around the function call to let the code continue.</p>
<p><pre><pre class="brush:delphi">try
&nbsp;&nbsp;MyImpersonateUserToken(UserName, UserData);
except
end;

if UserData.Groups.IsMemberOf(&#039;Administrators&#039;) then
</pre></pre></p>
<p>Okay, everbody should see that this is a really ******* code and should not be left in this way.</p>
<p>If you make an habit from this you won&#8217;t miss the old way. Instead it takes less time to implement and I don&#8217;t mention the time searching for memory leaks.</p>
<p>Furthermore, I think it looks much better and besides of that it is really easy to read and understand.<br />
 However, the most important reason (for me) is that any user who calls this function incorrectly (e.g. user not found) gets a nasty exception thrown into the face.</p>
<p>These are the reasons why JWSCL throws exceptions in 99,99% of its methods instead of returning error values.<br class="spacer_" /></p>
<h4>I always use try/finally for memory allocations</h4>
<p>Programmers have a hard to find memory leaks. There are libraries (like JWSCL) that support smart pointers but Delphi comes also with &#8220;smart pointers&#8221; (besides interfaces). Although it needs some more work. If you have translated code from C to Delphi you have seen it maybe. I&#8217;m talking about &#8220;goto&#8221; statements in C code.</p>
<p><pre><pre class="brush:c">{
&nbsp;&nbsp;...
&nbsp;&nbsp;if (!GetTokenInformation(...))
&nbsp;&nbsp;&nbsp;&nbsp;goto exit_1;

goto exit_0;
:exit_1
&nbsp;&nbsp;CloseHandle(hToken);

:exit_0
return (result);
}
</pre></pre></p>
<p>In Delphi we don&#8217;t use goto because we were told that it is  bad habit. So we directly put the exit after each failed function called.</p>
<p><pre><pre class="brush:delphi">begin
&nbsp;&nbsp;...
&nbsp;&nbsp;if not GetToken(hToken) then
&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;result := true;
&nbsp;&nbsp;&nbsp;&nbsp;exit;
&nbsp;&nbsp;end;
&nbsp;&nbsp;if (not GetTokenInformation(...)) then
&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hToken);
&nbsp;&nbsp;&nbsp;&nbsp;result := FALSE;
&nbsp;&nbsp;&nbsp;&nbsp;exit;
&nbsp;&nbsp;end;

&nbsp;&nbsp;CloseHandle(hToken);
&nbsp;&nbsp;result := TRUE;
end;
</pre></pre></p>
<p>In more complex code you can easily miss a failure code path or miss to close a handle or free an object. So why don&#8217;t do it this way?</p>
<p><pre><pre class="brush:delphi">&nbsp;&nbsp;...
&nbsp;&nbsp;if not GetToken(hToken) then
&nbsp;&nbsp;&nbsp;&nbsp;raiseLastError;

&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;if (not GetTokenInformation(...)) then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raiseLastError;

&nbsp;&nbsp;&nbsp;&nbsp;if GetMeOutOfHere() then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit;
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hToken);
&nbsp;&nbsp;end;
end;
</pre></pre></p>
<p>The try/finally statement ensures that the code within finally is executed. It does not matter that an exception is raised (we know that already). Even if we call &#8220;exit&#8221; the finally part is also executed.</p>
<p>However, you need to make sure that the variables within finally are valid.</p>
<p>1. CloseHandle throws an exception if the handle is not valid. This only happens if it detects an attached debugger.</p>
<p>2. Free, FreeAndNil, FreeMem, Dispose will throw an exception depending on the content of the given pointer. In worst case nothing happens and you get garbage results anywhere else in your application.</p>
<p>So the correct way is to trap every allocated variable (pointer, class) in a separate try/finally statement.</p>
<p><pre><pre class="brush:delphi">New(Ptr);
try
&nbsp;&nbsp;MyClass := TMyClass.Create;
&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;...
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;FreeAndNil(MyClass);
&nbsp;&nbsp;end;
finally
&nbsp;&nbsp;Dispose(Ptr);
&nbsp;&nbsp;Ptr := nil;
end;
</pre></pre></p>
<p>Make it an habit to implement the finally part immediately. Delphi helps you by adding the finally part automatically.</p>
<p><pre><pre class="brush:delphi">New(Ptr);
try
&nbsp;&nbsp;(1)
finally
&nbsp;&nbsp;Dispose(Ptr);
&nbsp;&nbsp;Ptr := nil;
end;
</pre></pre></p>
<p>Now continue at position (1).</p>
<p>One more tip:  If you have a lot of source lines between try/finally you can also put a comment behind finally to show the initial call.</p>
<p><pre><pre class="brush:delphi">New(Ptr);
try
&nbsp;&nbsp;... many lines ...
finally //New(Ptr);
&nbsp;&nbsp;Dispose(Ptr);
&nbsp;&nbsp;Ptr := nil;
end;
</pre></pre></p>
<p>In this way you don&#8217;t mix up the variable names allocated and freed. And we also don&#8217;t mix up the allocation types (e.g. GetMem &lt;&gt; Dispose)</p>
<p><br class="spacer_" /></p>
<h3>Your programming habits</h3>
<p>If you want to share your habits you can do this by leaving a comment. Or better you can write your own article and link it here so a conection is made.</p>
<p>Looking forward to hearing from you!</p>
<p><br class="spacer_" /></p>
<p>Christian</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/01/14/programming-habits/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Bugfix in JwsclTerminalServer</title>
		<link>http://blog.delphi-jedi.net/2010/01/13/bugfix-in-jwsclterminalserver/</link>
		<comments>http://blog.delphi-jedi.net/2010/01/13/bugfix-in-jwsclterminalserver/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 12:43:20 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2010/01/13/bugfix-in-jwsclterminalserver/</guid>
		<description><![CDATA[I just commited (revision 843) a little bugfix that existed since revision 833. In TJwWTSSession.Create LocalFree was called (after StrConnect) without LocalAlloc. Since utildll.dll handles the memory allocation is it not needed at all.
[Update]
The fix is currently only available in the developer version repository (aka trunk) of Subversion.
]]></description>
			<content:encoded><![CDATA[<p>I just commited (revision 843) a little bugfix that existed since revision 833. In TJwWTSSession.Create LocalFree was called (after StrConnect) without LocalAlloc. Since utildll.dll handles the memory allocation is it not needed at all.</p>
<p>[Update]<br />
The fix is currently only available in the developer version repository (aka trunk) of Subversion.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/01/13/bugfix-in-jwsclterminalserver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improvements to Jwscl&#8217;s Terminal Server unit</title>
		<link>http://blog.delphi-jedi.net/2010/01/08/improvements-to-jwscls-terminal-server-unit/</link>
		<comments>http://blog.delphi-jedi.net/2010/01/08/improvements-to-jwscls-terminal-server-unit/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 15:38:05 +0000</pubDate>
		<dc:creator>Remko</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=595</guid>
		<description><![CDATA[I have just commited an updated version of my Terminal Server unit (revision 842) into SVN. I have done some tests on Windows 7 (a fix for Windows 7 was done in Jwa revision 830 btw) and all seems to work well.
Internally the Connect method of TJwTerminalServer verifies the connection to Terminal Server by reading [...]]]></description>
			<content:encoded><![CDATA[<p>I have just commited an updated version of my <a href="http://jwscldoc.delphi-jedi.net/index.html?frmname=topic&amp;frmfile=JwsclTerminalServer_pas.html">Terminal Server unit</a> (revision 842) into SVN. I have done some tests on Windows 7 (a fix for Windows 7 was done in Jwa revision 830 btw) and all seems to work well.</p>
<p>Internally the <a href="http://jwscldoc.delphi-jedi.net/TJwTerminalServer_Connect.html">Connect</a> method of TJwTerminalServer verifies the connection to Terminal Server by reading some property. This is done because of a change in the API&#8217;s by Microsoft: opening a handle with WTSOpenServer to a nonexisting server actually returns a valid handle. I reported this as a bug to Microsoft some time ago and the &#8220;fixed it&#8221; by changing the <a href="http://msdn.microsoft.com/en-us/library/aa383837%28VS.85%29.aspx">documentation</a>.</p>
<p>For those interested in the code: it is a class function called IsValidServerHandle which can be used to verify a handle returned by WTSOpenServer:</p>
<p><pre><pre class="brush:delphi">class function TJwTerminalServer.IsValidServerHandle(const hServer: THandle): Boolean;
var
&nbsp;&nbsp;dwSize: DWORD;
&nbsp;&nbsp;WinStaInfo: WINSTATIONINFORMATIONW;
begin
&nbsp;&nbsp;{ All Windows &lt; Vista return 0 on Invalid handle }
&nbsp;&nbsp;Result := hServer &lt;&gt; 0;

&nbsp;&nbsp;{ No need to continue if it&#039;s already invalid... }
&nbsp;&nbsp;if not Result then
&nbsp;&nbsp;&nbsp;&nbsp;Exit;

&nbsp;&nbsp;{ For Windows &gt;= Vista we need to make a query to be sure
&nbsp;&nbsp;&nbsp;&nbsp;A non valid connection will fail on WTSQuerySessionInformation and will
&nbsp;&nbsp;&nbsp;&nbsp;return LastError RPC_S_SERVER_UNAVAILABLE }
&nbsp;&nbsp;if (TJwWindowsVersion.IsWindowsVista(True)) or
&nbsp;&nbsp;&nbsp;&nbsp;(TJwWindowsVersion.IsWindows2008(True)) then
&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;Result := WinStationQueryInformationW(hServer, 65536, WinStationInformation,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@WinStaInfo, sizeof(WinStaInfo), dwSize) or (GetLastError() &lt;&gt; RPC_S_SERVER_UNAVAILABLE);
&nbsp;&nbsp;end;
end;</pre></pre></p>
<p>A more visible change is the introduction of the Session function of TJwTerminalServer, with this function you can get all details for a specific session. It is meant for those cases where you need only one specific session and is of course far more efficient than enumerating all sessions, retrieving all sessions details and then finding the particular session in the SessionList.</p>
<p>The signature of the function is:</p>
<p><pre><pre class="brush:delphi">function TJwTerminalServer.Session(const SessionId: TJwSessionId = WTS_CURRENT_SESSION): TJwWTSSession;
</pre></pre></p>
<p>Note that the parameter is default so you can call both:</p>
<p><pre class="brush:delphi">Session := TS.Session;&nbsp;&nbsp;// Retrieve the current Session</pre></p>
<p>and</p>
<p><pre class="brush:delphi">Session := TS.Session(1); // Retrieve the session with SessionId 1</pre></p>
<p>It is important to understand the difference between Session and Sessions: where Session returns an instance of <a href="http://jwscldoc.delphi-jedi.net/TJwWTSSession.html">TJwWTSSession</a>, SessionS returns a <a href="http://jwscldoc.delphi-jedi.net/TJwWTSSessionList.html">SessionList</a>. This is especially important because Session works with a SessionId parameters and Sessions (being a TObjectList descendant) is accessed with by Index which is just the position in the ObjectList.</p>
<p>If a Session is not found an EJwsclWinCallFailedException will be raised so you&#8217;d better wrap the call into a try..except handler!</p>
<p>The last remark is that you, the caller, are responsible for freeing the object so a more complete sample would be like this:</p>
<p><pre><pre class="brush:delphi">var
&nbsp;&nbsp;TS: TJwTerminalServer;
&nbsp;&nbsp;Session: TJwWTSSession;
begin
&nbsp;&nbsp;TS := TJwTerminalServer.Create;
&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session := TS.Session;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Work with the session object
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ShowMessageFmt(&#039;Username=%s&#039;, [Session.Username]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session.PostMessage(&#039;Hello from the Jedi guys!&#039;, &#039;Message&#039;, MB_OK);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FreeAndNil(Session);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;&nbsp;&nbsp;except
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Handle Exception here!
&nbsp;&nbsp;&nbsp;&nbsp;end;
&nbsp;&nbsp;finally
&nbsp;&nbsp;&nbsp;&nbsp;FreeAndNil(TS);
&nbsp;&nbsp;end;
end;
</pre></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/01/08/improvements-to-jwscls-terminal-server-unit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows 2003 Server Requires StartServiceCtrlDispatcher&#8230;</title>
		<link>http://blog.delphi-jedi.net/2009/12/16/windows-2003-server-requires-startservicectrldispatcher/</link>
		<comments>http://blog.delphi-jedi.net/2009/12/16/windows-2003-server-requires-startservicectrldispatcher/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 10:50:39 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=586</guid>
		<description><![CDATA[&#8230; to be called before CoRegisterClassObject, which can be called indirectly by Application.Initialize.
You can see this comment at the beginning of a newly created service application. Unfortunately, today it is only half of the truth.
If you like to create a DCOM server in a service, and this is really easy if you know how to [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230; to be called before CoRegisterClassObject, which can be called indirectly by Application.Initialize.</p>
<p>You can see this comment at the beginning of a newly created service application. Unfortunately, today it is only half of the truth.</p>
<p><span id="more-586"></span>If you like to create a DCOM server in a service, and this is really easy if you know how to create in-process COM objects, then you need to know that Microsoft has changed the precondition for service initialization.</p>
<p><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/startservicectrldispatcher.asp">StartServiceCtrlDispatcher</a> reads:</p>
<p><cite>If a service runs in its own process, the main thread of the service process should immediately call StartServiceCtrlDispatcher. All initialization tasks are done in the service&#8217;s ServiceMain function when the service is started.</cite></p>
<p>Usually, the COM factories in Delphi register their classes before any of the user code is initialized. It is done in unit ComServ in procedure Initialization. There an initialization procedure (InitProc) is set for further processing.This is bad for services because the COM registration has to be done in the ServiceMain function (or just after the call) as MSDN states. If you ignore or forget it the creation of a COM object (in the client) fails after some time (usually some minutes) with the error</p>
<p>CO_E_SERVER_EXEC_FAILURE ($80080005) : <cite>Server execution failed</cite></p>
<p>For this reason the comment was added to the service code:</p>
<p><pre><pre class="brush:delphi"> // Windows 2003 Server requires StartServiceCtrlDispatcher to be
 // called before CoRegisterClassObject, which can be called indirectly
 // by Application.Initialize. TServiceApplication.DelayInitialize allows
 // Application.Initialize to be called from TService.Main (after
 // StartServiceCtrlDispatcher has been called).
 //
 // Delayed initialization of the Application object may affect
 // events which then occur prior to initialization, such as
 // TService.OnCreate. It is only recommended if the ServiceApplication
 // registers a class object with OLE and is intended for use with
 // Windows 2003 Server.
 </pre></pre></p>
<p>Well, what I didn&#8217;t realize, and that I really blame myself for, was the fact that <strong>this condition also exists in Windows Vista and Windows 7</strong>.  So we need to set</p>
<p><pre class="brush:delphi">Application.DelayInitialize := true;</pre></p>
<p>not only in Windows Server 2003 but also in all new Windows versions like Vista, 7, 8 and so on. So don&#8217;t believe in what comments tell but start thinking&#8230; Lesson learned the hard way.</p>
<p>PS. Is it worth to file it in QC?</p>
<h2><span style="font-family: monospace,Courier New;">References</span></h2>
<p><em>QC Report 4722</em> : Service exposing COM interface does not work on windows 2003; http://qc.embarcadero.com/wc/qcmain.aspx?d=4722</p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2009/12/16/windows-2003-server-requires-startservicectrldispatcher/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
