<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Programming on Remko's Blog</title><link>https://remkoweijnen.nl/blog/categories/programming/</link><description>Recent content in Programming on Remko's Blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 08 Aug 2013 17:34:05 +0000</lastBuildDate><atom:link href="https://remkoweijnen.nl/blog/categories/programming/index.xml" rel="self" type="application/rss+xml"/><item><title>PNAgent Icon Data Algorithm</title><link>https://remkoweijnen.nl/blog/2013/08/08/pnagent-icon-data-algorithm/</link><pubDate>Thu, 08 Aug 2013 17:34:05 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2013/08/08/pnagent-icon-data-algorithm/</guid><description>&lt;p&gt;Some time ago I wrote about the &lt;a href="https://remkoweijnen.nl/blog/2012/02/13/scripting-citrix-online-plugin-settings/" target="_blank"&gt;PNAgent data&lt;/a&gt; that is stored in the registry in XML format.&lt;/p&gt;
&lt;p&gt;After that post &lt;a href="http://andrewmorgan.ie/" target="_blank"&gt;Andrew Morgan&lt;/a&gt; asked me if I could extract the PNAgent icons from the XML data.&lt;/p&gt;
&lt;p&gt;That got me interested so let&amp;rsquo;s look at this data!&lt;/p&gt;
&lt;p&gt;If you look at XML from PNAgent the icondata as in the AppData.Details.Icon node you&amp;rsquo;ll see something like this:&lt;/p&gt;
&lt;p&gt;&lt;a class="glightbox thickbox" href="https://remkoweijnen.nl/blog/wp-content/uploads/2013/08/image5.webp" data-type="image" data-gallery="post-3330"&gt;&lt;img loading="lazy" decoding="async" style="display: inline;" title="image" alt="image" src="https://remkoweijnen.nl/blog/wp-content/uploads/2013/08/image_thumb3.webp" width="408" height="369" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Seems like the icon data is stored/encrypted in a proprietary format.&lt;/p&gt;</description></item><item><title>Programmatically set Excel LinkedCell property with VBA</title><link>https://remkoweijnen.nl/blog/2013/05/22/programmatically-set-excel-linkedcell-property-with-vba/</link><pubDate>Wed, 22 May 2013 11:36:48 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2013/05/22/programmatically-set-excel-linkedcell-property-with-vba/</guid><description>&lt;p&gt;Yesterday I was working with an Excel document that contained Combobox form controls.&lt;/p&gt; &lt;p&gt;I wanted to count the number of cells containing a particular value using the &lt;a href="http://office.microsoft.com/en-001/excel-help/countif-function-HP010342346.aspx" target="_blank"&gt;COUNTIF&lt;/a&gt; formula. However the count returned 0 because the LinkedCell property of the Combobox was not set to the Cell that contained the Combobox.&lt;/p&gt; &lt;p&gt;To set the LinkedCell Ctrl-Click the Combobox to select it, right-click and select Format Control. Then set the correct Cell in the Cell link field:&lt;/p&gt; &lt;p&gt;&lt;a class="glightbox thickbox" href="https://remkoweijnen.nl/blog/wp-content/uploads/2013/05/SNAGHTML18f5a4ba.webp" data-type="image" data-gallery="post-3229"&gt;&lt;img loading="lazy" decoding="async" style="display: inline" title="SNAGHTML18f5a4ba" alt="SNAGHTML18f5a4ba" src="https://remkoweijnen.nl/blog/wp-content/uploads/2013/05/SNAGHTML18f5a4ba_thumb.webp" width="240" height="226" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;My sheet contained about 150 Comboboxes, so obviously I was going to do this using a script. I couldn't find anything useful with Google so I wrote my own Macro.&lt;/p&gt;</description></item><item><title>Scriptable Citrix Password Encoder</title><link>https://remkoweijnen.nl/blog/2013/03/19/scriptable-citrix-password-encoder/</link><pubDate>Tue, 19 Mar 2013 16:27:49 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2013/03/19/scriptable-citrix-password-encoder/</guid><description>&lt;p&gt;A while ago I &lt;a href="https://remkoweijnen.nl/blog/2012/05/13/encoding-and-decoding-citrix-passwords/"&gt;published&lt;/a&gt; a tool to Encode and Decode Citrix passwords. Today I am publishing a small update to this tool that makes it scriptable by adding a &lt;a href="http://en.wikipedia.org/wiki/Component_Object_Model" target="_blank"&gt;COM interface&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;If you start the tool without parameters you will get the GUI, just like before:&lt;/p&gt; &lt;p&gt;&lt;img loading="lazy" decoding="async" title="Citrix Password Hasher by Remko Weijnen" alt="Encrypt | Decrypt Password | Hash | Citrix | Ctx1" src="https://remkoweijnen.nl/blog/wp-content/uploads/2012/05/image_thumb3.webp" width="419" height="84" /&gt;&lt;/p&gt; &lt;p&gt;To use the COM interface you first need to register the executable with the /regserver switch:&lt;/p&gt; &lt;p&gt;&lt;a class="glightbox thickbox" href="https://remkoweijnen.nl/blog/wp-content/uploads/2013/03/SNAGHTML185eb4ec.webp" data-type="image" data-gallery="post-3152"&gt;&lt;img loading="lazy" decoding="async" style="display: inline" title="Register CtxPass" alt="CtxPass /RegServer" src="https://remkoweijnen.nl/blog/wp-content/uploads/2013/03/SNAGHTML185eb4ec_thumb.webp" width="414" height="64" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;After the registration you can call it using any language that supports COM. To get you started I wrote a few examples&lt;/p&gt;</description></item><item><title>MSCOMM32.OCX returns error 80040112</title><link>https://remkoweijnen.nl/blog/2013/03/13/mscomm32-ocx-returns-error-80040112/</link><pubDate>Wed, 13 Mar 2013 15:58:39 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2013/03/13/mscomm32-ocx-returns-error-80040112/</guid><description>&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/2013/03/11/the-case-of-the-com-port-redirection/"&gt;Yesterday&lt;/a&gt; I wrote about troubleshooting an application that used Com Port redirection in Citrix.&lt;/p&gt; &lt;p&gt;During the troubleshoot I noticed that the application used an ActiveX component, MSCOMM32.OCX, for serial communication.&lt;/p&gt; &lt;p&gt;I wanted to quickly test if the component was correctly registered so I searched the registry from HKEY_CLASSES_ROOT for mscomm32.ocx.&lt;/p&gt;</description></item><item><title>Cannot redeclare class Snoopy</title><link>https://remkoweijnen.nl/blog/2013/01/14/cannot-redeclare-class-snoopy/</link><pubDate>Mon, 14 Jan 2013 19:31:34 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2013/01/14/cannot-redeclare-class-snoopy/</guid><description>&lt;p&gt;After installing a new Plugin in WordPress called &lt;a href="http://wordpress.org/extend/plugins/native-apps-builder/"&gt;Native Apps Builder&lt;/a&gt; I got the following error when I tried to go to the Plugin's settings:&lt;/p&gt; &lt;p&gt;&lt;a class="glightbox thickbox" href="https://remkoweijnen.nl/blog/wp-content/uploads/2013/01/image12.webp" data-type="image" data-gallery="post-2990"&gt;&lt;img loading="lazy" decoding="async" style="background-image: none; border-right-width: 0px; margin: 0px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="left" src="https://remkoweijnen.nl/blog/wp-content/uploads/2013/01/image_thumb12.webp" width="50" height="56" /&gt;&lt;/a&gt;Fatal error: Cannot redeclare class Snoopy in www/blog/wp-content/plugins/native-apps-builder/appsbuilderapi.php on line 34&lt;/p&gt; &lt;p&gt;This error is caused because a class named &amp;quot;Snoopy&amp;quot; is being declared twice. I figured that two plugins were incompatible with each other so I first needed to know which ones.&lt;/p&gt;</description></item><item><title>Decoding Citrix IMA Datastore Password</title><link>https://remkoweijnen.nl/blog/2012/05/29/decoding-citrix-ima-datastore-password/</link><pubDate>Tue, 29 May 2012 21:46:30 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2012/05/29/decoding-citrix-ima-datastore-password/</guid><description>&lt;p&gt;This morning &lt;a href="http://www.twitter.com/arbeijer/status/207398601066942464"&gt;Arjan Beijer&lt;/a&gt; sent me an interesting link to a &lt;a href="http://www.youtube.com/watch?v=Cb8-kvJkojY"&gt;youtube video&lt;/a&gt; about obtaining the Citrix IMA Datastore password using Windbg.&lt;/p&gt;
&lt;p&gt;The video shows a method, discovered by &lt;a href="https://twitter.com/#!/fdwl"&gt;Denis Gundarev&lt;/a&gt; to obtain the IMA Datastore password. Basically he uses DSMaint.exe and set&amp;rsquo;s a breakpoint on the call to &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa380882(v=vs.85).aspx"&gt;CryptUnprotectData&lt;/a&gt; and then reads the password from memory.&lt;/p&gt;
&lt;p&gt;I tried to call the CryptUnprotectData API with the data read from the registry directly but this failed with error NTE_BAD_KEY_STATE, this is defined in winerror.h and it means &amp;ldquo;Key not valid for use in specified state&amp;rdquo;.&lt;/p&gt;</description></item><item><title>Changing the RNS 510 startup logo</title><link>https://remkoweijnen.nl/blog/2011/08/31/changing-the-rns-510-startup-logo/</link><pubDate>Wed, 31 Aug 2011 17:20:18 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/08/31/changing-the-rns-510-startup-logo/</guid><description>&lt;p&gt;I wrote &lt;a href="https://remkoweijnen.nl/blog/2011/05/04/vw-rns-510-navigation-startup-pictures/" target="_blank"&gt;earlier&lt;/a&gt; about the startup logo's on the Volkswagen RNS 510 navigation.&lt;/p&gt; &lt;p&gt;Today I can finally tell you that I succeeded! &lt;br /&gt;I changed the startup logo to the logo from the MFD2 DVD as you can seen on this picture:&lt;/p&gt;</description></item><item><title>GetUserObjectInformation fails with Access Denied</title><link>https://remkoweijnen.nl/blog/2011/08/16/getuserobjectinformation-fails-with-access-denied/</link><pubDate>Tue, 16 Aug 2011 21:11:01 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/08/16/getuserobjectinformation-fails-with-access-denied/</guid><description>&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2011/08/image2.webp" class="glightbox" data-type="image" data-gallery="post-1994"&gt;&lt;img loading="lazy" decoding="async" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="Logon SID" border="0" alt="Logon SID" align="left" src="https://remkoweijnen.nl/blog/wp-content/uploads/2011/08/image_thumb2.webp" width="48" height="44" /&gt;&lt;/a&gt;Today I was reusing some old (pre vista) code the retrieves the Logon SID that I wrote a few years ago. The Logon SID is a special SID that identifies a logon session that has the form S-1-5-5-X-Y.&lt;/p&gt; &lt;p&gt;You can view your Logon SID with Process Explorer, right click a GUI process, select Properties and goto the Security Tab:&lt;/p&gt; &lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2011/08/SNAGHTML1b84fe6b.webp" class="glightbox" data-type="image" data-gallery="post-1994"&gt;&lt;img loading="lazy" decoding="async" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="explorer.exe:4484 Properties" border="0" alt="Process Explorer|Security Tab|Logon SID" src="https://remkoweijnen.nl/blog/wp-content/uploads/2011/08/SNAGHTML1b84fe6b_thumb.webp" width="274" height="317" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;#160;&lt;/p&gt;</description></item><item><title>GetTokenInformation with TokenLinkedToken returns error 1312</title><link>https://remkoweijnen.nl/blog/2011/08/11/gettokeninformation-with-tokenlinkedtoken-returns-error-1312/</link><pubDate>Thu, 11 Aug 2011 11:30:47 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/08/11/gettokeninformation-with-tokenlinkedtoken-returns-error-1312/</guid><description>&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/aa446671(v=vs.85).aspx" target="_blank"&gt;GetTokenInformation&lt;/a&gt; function can be used with the TokenLinkedToken Information Class on Windows Vista and higher to the linked (Elevated) token.&lt;/p&gt;
&lt;p&gt;This is useful when User Account Control is enabled and you want to launch an elevated process e.g. from a service.&lt;/p&gt;</description></item><item><title>Programmatically Check if User Account Control is Enabled</title><link>https://remkoweijnen.nl/blog/2011/08/11/programmatically-check-if-user-account-control-is-enabled/</link><pubDate>Thu, 11 Aug 2011 11:27:13 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/08/11/programmatically-check-if-user-account-control-is-enabled/</guid><description>&lt;p&gt;&lt;img style="margin: 0px 10px 0px 0px; display: inline; float: left" align="left" src="http://www.security.nl/image/3420" width="28" height="34" /&gt;Snippet below can be used to programmatically determine if User Account Control is enabled:&lt;/p&gt; 
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;objectpascal&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".pas" href="data:text/plain;charset=utf-8;base64,dXNlcwogIEp3YVdpbmJhc2UsIEp3YVdpbk50OwoKZnVuY3Rpb24gSXNVQUNFbmFibGVkOiBCb29sZWFuOwp2YXIKICBoVG9rZW46IFRIYW5kbGU7CiAgdGV0OiBUT0tFTl9FTEVWQVRJT05fVFlQRTsKICBkd1NpemU6IERXT1JEOwpiZWdpbgogIFdpbjMyQ2hlY2soT3BlblByb2Nlc3NUb2tlbihHZXRDdXJyZW50UHJvY2VzcywgVE9LRU5fUVVFUlksIGhUb2tlbikpOwogIC8vIFRva2VuRWxldmF0aW9uVHlwZSBjbGFzcyBvbmx5IGF2YWlsYWJsZSBvbiBWaXN0YSsKICBXaW4zMkNoZWNrKEdldFRva2VuSW5mb3JtYXRpb24oaFRva2VuLCBUb2tlbkVsZXZhdGlvblR5cGUsIEB0ZXQsIFNpemVPZih0ZXQpLCBkd1NpemUpKTsKCiAgUmVzdWx0IDo9IHRldCA8PiBUb2tlbkVsZXZhdGlvblR5cGVEZWZhdWx0OwplbmQ7"&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-objectpascal" data-lang="objectpascal"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;uses&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;JwaWinbase&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;JwaWinNt&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;IsUACEnabled&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;var&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;hToken&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;THandle&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;tet&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;TOKEN_ELEVATION_TYPE&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;dwSize&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;DWORD&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;Win32Check&lt;span class="o"&gt;(&lt;/span&gt;OpenProcessToken&lt;span class="o"&gt;(&lt;/span&gt;GetCurrentProcess&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;TOKEN_QUERY&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;hToken&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// TokenElevationType class only available on Vista+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;Win32Check&lt;span class="o"&gt;(&lt;/span&gt;GetTokenInformation&lt;span class="o"&gt;(&lt;/span&gt;hToken&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;TokenElevationType&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;tet&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;SizeOf&lt;span class="o"&gt;(&lt;/span&gt;tet&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dwSize&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ge"&gt;Result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tet&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;TokenElevationTypeDefault&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section class="comments"&gt;
&lt;h2&gt;1 Comments&lt;/h2&gt;
&lt;ol class="comment-list"&gt;
&lt;li class="comment depth-0"&gt;&lt;div class="comment-meta"&gt;&lt;span class="comment-author"&gt;&lt;a href="https://remkoweijnen.nl/blog/2011/08/11/gettokeninformation-with-tokenlinkedtoken-returns-error-1312/" rel="nofollow ugc"&gt;GetTokenInformation with TokenLinkedToken returns error 1312&lt;/a&gt;&lt;/span&gt; &lt;time datetime="2011-08-11"&gt;Aug 11, 2011&lt;/time&gt;&lt;/div&gt;&lt;div class="comment-body"&gt;&lt;p&gt;[...] specified logon session does not exist. It may already have been terminated.&amp;#8221;So you should check if User Account Control is enabled in such cases (or make this error non critical).share: Bookmark on Delicious Digg this post [...]&lt;/p&gt;</description></item><item><title>AD Internals: Display RID Allocation Pools</title><link>https://remkoweijnen.nl/blog/2011/06/27/ad-internals-display-rid-allocation-pools/</link><pubDate>Mon, 27 Jun 2011 15:37:04 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/06/27/ad-internals-display-rid-allocation-pools/</guid><description>&lt;p&gt;In my previous post I wrote about a problem I had with duplicate RID Allocation pools. &lt;/p&gt; &lt;p&gt;But how do we get more insight into these RID Allocation pools?&lt;/p&gt; &lt;p&gt;The DCDIAG tool can display this information per domain controleler using the following syntax&lt;/p&gt; 
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;batch&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".bat" href="data:text/plain;charset=utf-8;base64,ZGNkaWFnIC9zOnNlcnZlciAvdiAvdGVzdDpyaWRtYW5hZ2Vy"&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-batch" data-lang="batch"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dcdiag /s:server /v /test:ridmanager&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Example output:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2011/06/image28.webp" class="glightbox" data-type="image" data-gallery="post-1950"&gt;&lt;img loading="lazy" decoding="async" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DCDiag Ridmanager Test" border="0" alt="DCDiag Ridmanager Test" src="https://remkoweijnen.nl/blog/wp-content/uploads/2011/06/image_thumb28.webp" width="419" height="85" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But where in Active Directory is this information stored and can we display it for all Domain Controllers at once for larger environments?&lt;/p&gt;</description></item><item><title>Determining stack size</title><link>https://remkoweijnen.nl/blog/2011/05/27/determining-stack-size/</link><pubDate>Fri, 27 May 2011 15:10:00 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/05/27/determining-stack-size/</guid><description>&lt;p&gt;I just read an answer on &lt;a href="http://stackoverflow.com/questions/6150018/what-is-a-safe-maximum-stack-size-or-how-to-measure-use-of-stack" target="_blank"&gt;StackOverflow&lt;/a&gt; with this code:&lt;/p&gt; 
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;objectpascal&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".pas" href="data:text/plain;charset=utf-8;base64,dmFyCiAgZXU6RFdPUkQ7CmJlZ2luCiAgYXNtCiAgICBtb3YgZWF4LFtmczokNF0KICAgIG1vdiBlYngsW2ZzOiQ4XQogICAgc3ViIGVheCxlYngKICAgIG1vdiBldSxlYXgKICBlbmQ7CgogIFNob3dNZXNzYWdlKEludFRvU3RyKGV1KSk7CmVuZDs="&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-objectpascal" data-lang="objectpascal"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;var&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;eu&lt;span class="o"&gt;:&lt;/span&gt;DWORD&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;asm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;mov&lt;span class="w"&gt; &lt;/span&gt;eax&lt;span class="p"&gt;,[&lt;/span&gt;fs&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;$4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;mov&lt;span class="w"&gt; &lt;/span&gt;ebx&lt;span class="p"&gt;,[&lt;/span&gt;fs&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;$8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;sub&lt;span class="w"&gt; &lt;/span&gt;eax&lt;span class="p"&gt;,&lt;/span&gt;ebx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;mov&lt;span class="w"&gt; &lt;/span&gt;eu&lt;span class="p"&gt;,&lt;/span&gt;eax
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;ShowMessage&lt;span class="o"&gt;(&lt;/span&gt;IntToStr&lt;span class="o"&gt;(&lt;/span&gt;eu&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Unfortunately it lacked explanation, so what does this code do?&lt;/p&gt;</description></item><item><title>How Outlook and Exchange handle Timezones</title><link>https://remkoweijnen.nl/blog/2011/05/18/how-outlook-and-exchange-handle-timezones/</link><pubDate>Wed, 18 May 2011 19:53:27 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/05/18/how-outlook-and-exchange-handle-timezones/</guid><description>&lt;p&gt;Again an old war story, this time about timezone handling in Outlook/Exchange.&lt;/p&gt; &lt;p&gt;I am not sure which year it was but I had just started to work for a new company and inherited an Exchange 5.5 Server.&lt;/p&gt; &lt;p&gt;The mail had been migrated from an earlier version and calendar data was migrated from &lt;a href="http://en.wikipedia.org/wiki/Microsoft_Schedule_Plus" target="_blank"&gt;Schedule+&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;On the first change to Daylight Savings (DTS) all recurring appointments where shown one hour later (or earlier can't remember) in Outlook. A manual change was not an option: there were over 2000 mailboxes each with a lot of appointments.&lt;/p&gt; &lt;p&gt;We first tried a workaround by disabling DTS on the the workstations and then manually change the time when changing from and to DTS.&amp;#160; &lt;/p&gt; &lt;p&gt;But this influenced the timestamps on externals mails and of course appointments with external parties.&lt;/p&gt; &lt;p&gt;After a lot of (and I really mean a lot) of researching I found that Outlook stores all times in an appointment as relative (UTC) time. &lt;/p&gt; &lt;p&gt;Upon display it uses an undocumented TimeZone descriptor field to convert to Local Time.&lt;/p&gt; &lt;p&gt;&amp;#160;&lt;/p&gt;</description></item><item><title>Stuff from an ancient past</title><link>https://remkoweijnen.nl/blog/2011/05/18/stuff-from-an-ancien-past/</link><pubDate>Wed, 18 May 2011 10:08:35 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/05/18/stuff-from-an-ancien-past/</guid><description>&lt;p&gt;I just found a very old backup file containing old source code for a few tools I wrote ages ago.&lt;/p&gt; &lt;p&gt;This was in 1997 on my first job for a company called PTT Telecom (the Dutch Telecoms) and I wrote some tools to make life easier.&lt;/p&gt; &lt;p&gt;They were all written in Turbo Pascal and supported Long Filenames when running under Windows '95 (there was a trick to do that under DOS).&lt;/p&gt; &lt;p&gt;The first tool was called Retreive Tool, it parsed a backup file from a private branch exchange (PBX) and could make reports about Licensing, the hardware in the PBX, Extension numbers and their hardware positions and so on.&lt;/p&gt; &lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2011/05/image13.webp" class="glightbox" data-type="image" data-gallery="post-1757"&gt;&lt;img loading="lazy" decoding="async" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://remkoweijnen.nl/blog/wp-content/uploads/2011/05/image_thumb13.webp" width="421" height="199" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;#160;&lt;/p&gt;</description></item><item><title>Autologon user on Windows XP/2003 using AutoReconnect pipe - part 3 (implementation details)</title><link>https://remkoweijnen.nl/blog/2011/03/03/autologon-user-on-windows-xp2003-using-autoreconnect-pipe-part-3-implementation-details/</link><pubDate>Thu, 03 Mar 2011 13:00:46 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/03/03/autologon-user-on-windows-xp2003-using-autoreconnect-pipe-part-3-implementation-details/</guid><description>&lt;p&gt;In the previous parts (&lt;a href="https://remkoweijnen.nl/blog/2011/02/09/autologon-user-on-windows-xp2003-using-autoreconnect-pipe-part-1-theory/"&gt;part 1&lt;/a&gt; &lt;a href="https://remkoweijnen.nl/blog/2011/03/02/autologon-user-on-windows-xp2003-using-autoreconnect-pipe-part-2-problems-and-workarounds/"&gt;part 2&lt;/a&gt;) i&amp;rsquo;ve described the theoretical part and implementation problems. So, now we can write the code:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In case we login the user, we just call &lt;a href="http://msdn.microsoft.com/en-us/library/aa378292(v=vs.85).aspx"&gt;LsaLogonUser&lt;/a&gt; to get the token:&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Autologon user on Windows XP/2003 using AutoReconnect pipe - part 2 (problems and workarounds)</title><link>https://remkoweijnen.nl/blog/2011/03/02/autologon-user-on-windows-xp2003-using-autoreconnect-pipe-part-2-problems-and-workarounds/</link><pubDate>Wed, 02 Mar 2011 00:10:02 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/03/02/autologon-user-on-windows-xp2003-using-autoreconnect-pipe-part-2-problems-and-workarounds/</guid><description>&lt;p&gt;In &lt;a href="https://remkoweijnen.nl/blog/2011/02/09/autologon-user-on-windows-xp2003-using-autoreconnect-pipe-part-1-theory/"&gt;part 1&lt;/a&gt; I&amp;rsquo;ve described the theoretical parts needed for a custom autologon application implementation.&lt;/p&gt;
&lt;p&gt;But there are some practical problems which I will describe here.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I use the &lt;a href="http://msdn.microsoft.com/en-us/library/aa378292(v=vs.85).aspx"&gt;LsaLogonUser&lt;/a&gt; function to log in the user. However, if I do not pass not null for the &lt;em&gt;LocalGroups&lt;/em&gt; parameter, msgina.dll fails to process the logon.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Why? Because it looks for the &lt;strong&gt;SE_GROUP_LOGON_ID&lt;/strong&gt; SID and treat it as logon SID. So we have to add the logon SID manually:&lt;/p&gt;</description></item><item><title>Autologon user on Windows XP/2003 using AutoReconnect pipe - part 1 (theory)</title><link>https://remkoweijnen.nl/blog/2011/02/28/autologon-user-on-windows-xp2003-using-autoreconnect-pipe-part-1-theory/</link><pubDate>Mon, 28 Feb 2011 10:46:29 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/02/28/autologon-user-on-windows-xp2003-using-autoreconnect-pipe-part-1-theory/</guid><description>&lt;p&gt;Windows XP introduced the ability to use Fast User Switching (FUS from here on), which is implemented using &lt;em&gt;Terminal Services&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;But in some cases (i.e. when FUS is not enabled, or when you connect to the console in Windows 2003 server), the Winlogon process in an RDP session needs to transfer credentials to Session 0.&lt;/p&gt;
&lt;p&gt;Although not documented in MSDN, the process of transferring credentials is described by Keith Brown in the June 2005 issue of MSDN magazine: &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163786.aspx"&gt;Customizing GINA, Part 2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa380577(v=vs.85).aspx"&gt;WlxQueryConsoleSwitchCredentials&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/aa380563(v=vs.85).aspx"&gt;WlxGetConsoleSwitchCredentials&lt;/a&gt; are used in the transfer with the semi-documented &lt;strong&gt;WLX_SAS_TYPE_AUTHENTICATED&lt;/strong&gt; SAS code constant.&lt;/p&gt;
&lt;p&gt;Internally, &lt;em&gt;winlogon.exe&lt;/em&gt; uses a Named Pipe, &lt;strong&gt;\.\Pipe\TerminalServer\AutoReconnect, &lt;/strong&gt;to implement both of these functions.&lt;/p&gt;
&lt;p&gt;The pipe format is described in this structure:&lt;/p&gt;</description></item><item><title>Querying a user token under 64 bit version of 2003/XP</title><link>https://remkoweijnen.nl/blog/2011/01/29/querying-a-user-token-under-64-bit-version-of-2003xp/</link><pubDate>Sat, 29 Jan 2011 22:17:52 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/01/29/querying-a-user-token-under-64-bit-version-of-2003xp/</guid><description>&lt;p&gt;If you want to obtain a user&amp;rsquo;s token in a Terminal Server or Citrix session (eg to launch a process in a session) you can call the &lt;a href="http://msdn.microsoft.com/en-us/library/aa383840(v=vs.85).aspx"&gt;WTSQueryUserToken&lt;/a&gt; function.&lt;/p&gt;
&lt;p&gt;On the x64 versions of Windows XP and Server 2003 this function fails however and returns &lt;strong&gt;ERROR_INSUFFICIENT_BUFFER&lt;/strong&gt; (&amp;quot;&lt;em&gt;The data area passed to a system call is too small&lt;/em&gt;.&amp;quot;) when called from a 32 bit process.&lt;/p&gt;
&lt;p&gt;Internally WTSQueryUserToken calls the undocumented function &lt;a href="http://msdn.microsoft.com/en-us/library/aa383827(v=vs.85).aspx"&gt;WinstationQueryInformationW&lt;/a&gt; with the &lt;strong&gt;WinStationUserToken&lt;/strong&gt; class (14) and passing a &lt;a href="http://msdn.microsoft.com/en-us/library/cc248658(PROT.10).aspx"&gt;WINSTATIONUSERTOKEN&lt;/a&gt; struct, filled with caller ProcessId and ThreadId.&lt;/p&gt;
&lt;p&gt;But on x64 Windows the size of this structure is 24 bytes, while on 32 bit Windows the size of the structure is 12 bytes!&lt;/p&gt;</description></item><item><title>Enumerating Session Processes with NtQuerySystemInformation</title><link>https://remkoweijnen.nl/blog/2011/01/20/enumerating-session-process-with-ntquerysysteminformation/</link><pubDate>Thu, 20 Jan 2011 15:34:23 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/01/20/enumerating-session-process-with-ntquerysysteminformation/</guid><description>&lt;p&gt;As you may know, you can enumerate processes of a specific Terminal Server or Citrix session using the &lt;a href="http://msdn.microsoft.com/en-us/library/ms724509(VS.85).aspx"&gt;NtQuerySystemInformation&lt;/a&gt; function.&lt;/p&gt;
&lt;p&gt;On x86 system the code below works fine:&lt;/p&gt;
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;objectpascal&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".pas" href="data:text/plain;charset=utf-8;base64,dmFyCiAgU3RhdHVzIDogTlRTVEFUVVM7CiAgUmV0TGVuZ3RoIDogRFdPUkQ7CiAgU2Vzc2lvbkluZm8gOiAgU1lTVEVNX1NFU1NJT05fUFJPQ0VTU19JTkZPUk1BVElPTjsKICBDdXJyZW50UHJvY2VzcyA6IFBTeXN0ZW1Qcm9jZXNzZXM7CmJlZ2luCgogIFNlc3Npb25JbmZvLlNlc3Npb25JZCA6PSBTZXNzaW9uSWQ7CiAgU2Vzc2lvbkluZm8uQnVmZmVyIDo9IG5pbDsKICBTZXNzaW9uSW5mby5TaXplT2ZCdWYgOj0gMDsKCiAgU3RhdHVzIDo9IE50UXVlcnlTeXN0ZW1JbmZvcm1hdGlvbihTeXN0ZW1TZXNzaW9uUHJvY2Vzc2VzSW5mb3JtYXRpb24sIEBTZXNzaW9uSW5mbywgU2l6ZU9mKFNlc3Npb25JbmZvKSwgQFJldExlbmd0aCk7CiAgd2hpbGUgKFN0YXR1cyA9IFNUQVRVU19JTkZPX0xFTkdUSF9NSVNNQVRDSCkgZG8KICBiZWdpbgogICAgU2Vzc2lvbkluZm8uU2l6ZU9mQnVmIDo9IFJldExlbmd0aDsKICAgIFNlc3Npb25JbmZvLkJ1ZmZlciA6PSBHZXRNZW1vcnkoUmV0TGVuZ3RoKTsKICAgIHRyeQogICAgICBTdGF0dXMgOj0gTnRRdWVyeVN5c3RlbUluZm9ybWF0aW9uKFN5c3RlbVNlc3Npb25Qcm9jZXNzZXNJbmZvcm1hdGlvbiwgQFNlc3Npb25JbmZvLCBTaXplT2YoU2Vzc2lvbkluZm8pLCBAUmV0TGVuZ3RoKTsKICAgICAgaWYgTlRfU1VDQ0VTUyhTdGF0dXMpIHRoZW4KICAgICAgYmVnaW4KICAgICAgICBDdXJyZW50UHJvY2VzcyA6PSBTZXNzaW9uSW5mby5CdWZmZXI7CiAgICAgICAgd2hpbGUgVHJ1ZSBkbwogICAgICAgIGJlZ2luCiAgICAgICAgICAvLyBZb3VyIGNvZGUgaGVyZQoKICAgICAgICAgIGlmIChDdXJyZW50UHJvY2Vzc14uTmV4dEVudHJ5RGVsdGEgPSAwKSB0aGVuCiAgICAgICAgICAgIEJyZWFrOwoKICAgICAgICAgIENhcmRpbmFsKEN1cnJlbnRQcm9jZXNzKSA6PSBDYXJkaW5hbChDdXJyZW50UHJvY2VzcykgKyBDdXJyZW50UHJvY2Vzc14uTmV4dEVudHJ5RGVsdGE7CiAgICAgICAgZW5kOwoKICAgICAgICBFeGl0OwogICAgICBlbmQ7CiAgICBmaW5hbGx5CiAgICAgIEZyZWVNZW1vcnkoU2Vzc2lvbkluZm8uQnVmZmVyKTsKICAgIGVuZDsKICBlbmQ7CgogIFNldExhc3RFcnJvcihSdGxOdFN0YXR1c1RvRG9zRXJyb3IoU3RhdHVzKSk7CiAgUmFpc2VMYXN0T1NFcnJvcjsKZW5kOw=="&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-objectpascal" data-lang="objectpascal"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;var&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;Status&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NTSTATUS&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;RetLength&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;DWORD&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;SessionInfo&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;SYSTEM_SESSION_PROCESS_INFORMATION&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;CurrentProcess&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;PSystemProcesses&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;SessionInfo&lt;span class="p"&gt;.&lt;/span&gt;SessionId&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;SessionId&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;SessionInfo&lt;span class="p"&gt;.&lt;/span&gt;Buffer&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;SessionInfo&lt;span class="p"&gt;.&lt;/span&gt;SizeOfBuf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;Status&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NtQuerySystemInformation&lt;span class="o"&gt;(&lt;/span&gt;SystemSessionProcessesInformation&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;SessionInfo&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;SizeOf&lt;span class="o"&gt;(&lt;/span&gt;SessionInfo&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;RetLength&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;Status&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;STATUS_INFO_LENGTH_MISMATCH&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;SessionInfo&lt;span class="p"&gt;.&lt;/span&gt;SizeOfBuf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;RetLength&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;SessionInfo&lt;span class="p"&gt;.&lt;/span&gt;Buffer&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;GetMemory&lt;span class="o"&gt;(&lt;/span&gt;RetLength&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;Status&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NtQuerySystemInformation&lt;span class="o"&gt;(&lt;/span&gt;SystemSessionProcessesInformation&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;SessionInfo&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;SizeOf&lt;span class="o"&gt;(&lt;/span&gt;SessionInfo&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;RetLength&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;NT_SUCCESS&lt;span class="o"&gt;(&lt;/span&gt;Status&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;CurrentProcess&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;SessionInfo&lt;span class="p"&gt;.&lt;/span&gt;Buffer&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;True&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Your code here&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;CurrentProcess&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;NextEntryDelta&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;Break&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;Cardinal&lt;span class="o"&gt;(&lt;/span&gt;CurrentProcess&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Cardinal&lt;span class="o"&gt;(&lt;/span&gt;CurrentProcess&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;CurrentProcess&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;NextEntryDelta&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;Exit&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;finally&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;FreeMemory&lt;span class="o"&gt;(&lt;/span&gt;SessionInfo&lt;span class="p"&gt;.&lt;/span&gt;Buffer&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;SetLastError&lt;span class="o"&gt;(&lt;/span&gt;RtlNtStatusToDosError&lt;span class="o"&gt;(&lt;/span&gt;Status&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;RaiseLastOSError&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;While this works fine on Windows XP and 2003 x86, it fails to work correctly on the x64 versions of Windows XP and 2003 (or maybe even higher).&lt;/p&gt;
&lt;p&gt;The problem is that RetLength is always SizeOf(SYSTEM_SESSION_PROCESS_INFORMATION) and thus we are in an endless loop!&lt;/p&gt;</description></item><item><title>SasLibEx Screencast</title><link>https://remkoweijnen.nl/blog/2011/01/19/saslibex-screencast/</link><pubDate>Wed, 19 Jan 2011 22:36:44 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/01/19/saslibex-screencast/</guid><description>&lt;p&gt;I just recorded a SasLibEx Screencast, it shows some of the very powerfull features of SasLibEx.&lt;/p&gt;
&lt;p&gt;The following features are shown:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;span style="color: #35383d;"&gt;Simulate Ctrl Alt Del (Secure Attention Sequence)&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span style="color: #35383d;"&gt;Cancel Ctrl Alt Del&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span style="color: #35383d;"&gt;Lock Workstation&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span style="color: #35383d;"&gt;Unlock Workstation (without credentials)&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span style="color: #35383d;"&gt;Disable Ctrl Alt Del&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span style="color: #35383d;"&gt;Enable Ctrl Alt Del again&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span style="color: #35383d;"&gt;Cancel pending UAC request&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span style="color: #35383d;"&gt;Is Desktop Locked&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:8c371d04-5435-4a86-a54a-5611345258b5" class="wlWriterEditableSmartContent" style="margin: 0px; display: inline; float: none; padding: 0px;"&gt;
&lt;div&gt;&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="448" height="252" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="src" value="http://www.youtube.com/v/Nyl4_ECe5xI?hl=en&amp;amp;hd=1" /&gt;&lt;embed type="application/x-shockwave-flash" width="448" height="252" src="http://www.youtube.com/v/Nyl4_ECe5xI?hl=en&amp;amp;hd=1"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;div style="width: 448px; clear: both; font-size: 0.8em;"&gt;SasLibEx Feature Demo #1&lt;/div&gt;
&lt;/div&gt;
&lt;section class="comments"&gt;
&lt;h2&gt;1 Comments&lt;/h2&gt;
&lt;ol class="comment-list"&gt;
&lt;li class="comment depth-0"&gt;&lt;div class="comment-meta"&gt;&lt;span class="comment-author"&gt;&lt;a href="http://topsy.com/www.remkoweijnen.nl/blog/2011/01/19/saslibex-screencast/?utm_source=pingback&amp;amp;amp;utm_campaign=L2" rel="nofollow ugc"&gt;Tweets die vermelden SasLibEx Screencast | Remko Weijnen&amp;#x27;s Blog (Remko&amp;#x27;s Blog) -- Topsy.com&lt;/a&gt;&lt;/span&gt; &lt;time datetime="2011-01-20"&gt;Jan 20, 2011&lt;/time&gt;&lt;/div&gt;&lt;div class="comment-body"&gt;&lt;p&gt;[...] Dit blogartikel was vermeld op Twitter door Remko Weijnen, Remko Weijnen. Remko Weijnen heeft gezegd: First #SasLibEx ScreenCast! showing simulate ctrl alt del, unlock workstation without credentials, disable cad and more http://bit.ly/fFM8wB [...]&lt;/p&gt;</description></item><item><title>Convert Drive Bitmask to Drive Letter</title><link>https://remkoweijnen.nl/blog/2011/01/14/convert-drive-bitmask-to-drive-letter/</link><pubDate>Fri, 14 Jan 2011 11:06:03 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/01/14/convert-drive-bitmask-to-drive-letter/</guid><description>&lt;p&gt;I was writing a test program that will perform some actions when a USB Memory Stick is inserted.&lt;/p&gt; &lt;p&gt;When this happens Windows send a Broadcast a &lt;a href="http://msdn.microsoft.com/en-us/library/aa363480(VS.85).aspx" target="_blank"&gt;WM_DEVICECHANGE&lt;/a&gt; message.&lt;/p&gt; &lt;p&gt;The wParam member of this Message contains a (pointer to) a &lt;a href="http://msdn.microsoft.com/en-us/library/aa363246(VS.85).aspx" target="_blank"&gt;DEV_BROADCAST_HDR&lt;/a&gt; structure.&lt;/p&gt; &lt;p&gt;if the dbch_devicetype member of this structure is of type DBT_DEVTYP_VOLUME then we can cast the structure to &lt;a href="http://msdn.microsoft.com/en-us/library/aa363249(v=VS.85).aspx" target="_blank"&gt;DEV_BROADCAST_VOLUME&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Cannot Access Files, But Need the Origin?</title><link>https://remkoweijnen.nl/blog/2011/01/03/cannot-access-files-but-need-the-origin/</link><pubDate>Mon, 03 Jan 2011 09:52:20 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2011/01/03/cannot-access-files-but-need-the-origin/</guid><description>&lt;p&gt;Have you developed an application that accesses files and may stop because a file cannot be accessed but you need to?&lt;/p&gt;
&lt;p&gt;Since Windows Vista it is possible to find out the name of the application which holds open a file.&lt;/p&gt;</description></item><item><title>Packaging an Application that uses the BDE</title><link>https://remkoweijnen.nl/blog/2010/12/14/packaging-an-application-that-uses-the-bde/</link><pubDate>Tue, 14 Dec 2010 21:12:58 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/12/14/packaging-an-application-that-uses-the-bde/</guid><description>&lt;p&gt;Today I needed to package an application that uses the Borland Database Engine (BDE).&lt;/p&gt;
&lt;p&gt;The BDE is a database engine/connectivity component commonly used in Delphi and C++ Builder applications. It has been deprecated since 2000 when it was replaced by dbExpress.&lt;/p&gt;
&lt;p&gt;But it&amp;rsquo;s still widely used so you may still find applications that require the BDE.&lt;/p&gt;
&lt;p&gt;In my environment I already have a package for the BDE itsself. But the application I needed to package today, needs to have an Alias addded.&lt;/p&gt;
&lt;p&gt;This is usually done manually by going into the BDEADMIN control panel applet or by copying the file where BDE saves the aliases (IDAPI32.CFG).&lt;/p&gt;
&lt;p&gt;Here is a screenshot of the Alias my application needs (it uses an Interbase database):&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2010/12/bde.webp" class="glightbox" data-type="image" data-gallery="post-868"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2010/12/bde-small.webp" alt="BDE" width="430" height="302" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t like the copy approach and didn&amp;rsquo;t even consider the manual option so I wrote 2 little tools.&lt;/p&gt;</description></item><item><title>Where is LSA_OBJECT_ATTRIBUTES defined?</title><link>https://remkoweijnen.nl/blog/2010/12/12/where-is-lsa_object_attributes-defined/</link><pubDate>Sun, 12 Dec 2010 23:06:20 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/12/12/where-is-lsa_object_attributes-defined/</guid><description>&lt;p&gt;If you read MSDN documentation for &lt;a title="LSA_OBJECT_ATTRIBUTES Structure" href="http://msdn.microsoft.com/en-us/library/ms721829(v=vs.85).aspx" target="_blank"&gt;LSA_OBJECT_ATTRIBUTES&lt;/a&gt; you will think it's defined in LsaLookup.h:&lt;/p&gt;
&lt;p align="center"&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2010/12/msdn.webp" class="glightbox" data-type="image" data-gallery="post-853"&gt;&lt;img loading="lazy" decoding="async" alt="MSDN" src="https://remkoweijnen.nl/blog/wp-content/uploads/2010/12/msdn-small.webp" width="430" height="121" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And that it's supported since Windows 2000 but I couldn't find it in this header file.&lt;/p&gt;
&lt;p&gt;Instead I found it in NTSecAPI.h, so I decided to check the different SDK versions and starting from SDK v7 LsaLookup.h exists but in earlier SDK's (v5.0, v6.0a and v6.1) there is no LsaLookup.h.&lt;/p&gt;</description></item><item><title>Altiris Job Builder</title><link>https://remkoweijnen.nl/blog/2010/11/23/altiris-job-builder/</link><pubDate>Tue, 23 Nov 2010 10:26:34 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/11/23/altiris-job-builder/</guid><description>&lt;p&gt;I have created a little tool for myself that I have call Altiris Job Builder, it retreives the Jobs from the Altiris database and shows them in a Treeview.&lt;/p&gt;
&lt;p&gt;Then I can assemble a Master Build Job by dragging the needed Jobs to another Treeview on the right. Since it&amp;rsquo;s just for me it doesn&amp;rsquo;t have a fancy gui:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2010/11/jobbuilder2.webp" class="glightbox" data-type="image" data-gallery="post-784"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2010/11/jobbuilder2-small.webp" alt="JobBuilder2" width="430" height="406" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So why did I write it? Well I have divided my Jobs into Prerequisites and Packages, for instance IIS and Terminal Server and Java are prereqisuites for Citrix. But many prereqisuites are required for one or more other packages, eg Java is also used for certain applications.&lt;/p&gt;</description></item><item><title>Programmatically Changing the Driver Signing options</title><link>https://remkoweijnen.nl/blog/2010/11/11/programmatically-changing-the-driver-signing-options/</link><pubDate>Thu, 11 Nov 2010 09:57:17 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/11/11/programmatically-changing-the-driver-signing-options/</guid><description>&lt;p&gt;Today I was tested my unattended Citrix installation (XenApp 5 on Windows 2003) and I noticed that the install was taking longer than expected.&lt;/p&gt;
&lt;p&gt;This was because of a popup:&lt;/p&gt;
&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2010/11/driversigning-1.webp" alt="DriverSigning" width="411" height="335" /&gt;
&lt;p&gt;I am not sure if this popup is shown because I ran MsiExec with /Qb- (I usually do that when testing) but if the Popup is not shown it means that at least the installation of this driver (probably Citrix Universal Print driver) fails.&lt;/p&gt;
&lt;p&gt;So this means I needed to script turning off Driver Signature Warnings. A quick search led me to kb article &lt;a title="Driver signing registry values cannot be modified directly in Windows" href="http://support.microsoft.com/kb/298503" target="_blank"&gt;kb298503&lt;/a&gt; which is titled &amp;ldquo;&lt;em&gt;Driver signing registry values cannot be modified directly in Windows&lt;/em&gt;&amp;rdquo;. As you may guess that title drew my attention.&lt;/p&gt;</description></item><item><title>Automatically Accept Shadow Request</title><link>https://remkoweijnen.nl/blog/2010/10/22/automatically-accept-shadow-request/</link><pubDate>Fri, 22 Oct 2010 17:04:00 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/10/22/automatically-accept-shadow-request/</guid><description>&lt;p&gt;When you request Shadow (Remote Control) of a Remote Desktop (Terminal Server) or Citrix session the user gets a Dialog where he can Accept or Deny the Shadow Request.&lt;/p&gt;
&lt;p&gt;It looks something like this:&lt;/p&gt;
&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2010/10/shadowrequest.webp" alt="ShadowRequest" width="396" height="152" /&gt;
&lt;p&gt;It&amp;rsquo;s possible to change the default settings and remove the need for this permission but I think this is a bad idea since it violates the user&amp;rsquo;s privacy.&lt;/p&gt;
&lt;p&gt;But sometimes it would be convenient to automatically accept, for instance for when a user is away or when you want to shadow a session that is &amp;ldquo;yours&amp;rdquo; but runs under another account.&lt;/p&gt;
&lt;p&gt;I wrote a tool to do just that :D&lt;/p&gt;</description></item><item><title>Change Driveletter Commandline Tool</title><link>https://remkoweijnen.nl/blog/2010/10/20/change-driveletter-commandline-tool/</link><pubDate>Wed, 20 Oct 2010 14:04:35 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/10/20/change-driveletter-commandline-tool/</guid><description>&lt;p&gt;Some time ago (2008 actually) I wrote a &lt;a href="https://remkoweijnen.nl/blog/2008/12/09/commandline-tool-to-change-drive-letter-assignment/" target="_blank"&gt;tool that can assign driveletters&lt;/a&gt; given a volumename. I use it myself after SysPrep operations to assign the desired drive letters. For instance after cloning a Virtual Machine from a template.&lt;/p&gt;
&lt;p&gt;I noticed that I updated this tool sometime after the original post but never uploaded it here. The most important changes are:&lt;/p&gt;</description></item><item><title>SasLibEx 2.0 Release Announcement</title><link>https://remkoweijnen.nl/blog/2010/09/15/saslibex-2-0-release-announcement/</link><pubDate>Wed, 15 Sep 2010 14:34:08 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/09/15/saslibex-2-0-release-announcement/</guid><description>&lt;p&gt;Today I can proudly announce the official release of SasLibEx 2.0 which will bring support for new compilers, a native x64 version and some exciting new features!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;New Compilers:&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SasLibEx 2.0 introduces support for Visual Studio 2010 (C++), RAD Studio 2010 (Delphi and C++ personalities) and the new RAD Studio XE (Delphi and C++).&lt;/p&gt;</description></item><item><title>Fun with asm</title><link>https://remkoweijnen.nl/blog/2010/06/18/fun-with-asm/</link><pubDate>Fri, 18 Jun 2010 12:02:00 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/06/18/fun-with-asm/</guid><description>&lt;p&gt;Today just some fun stuff with ASM, probably not the most recommended way to do things but for sure the most geeky way :P&lt;/p&gt;
&lt;p&gt;Get the Current Session Id:&lt;/p&gt;
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;objectpascal&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".pas" href="data:text/plain;charset=utf-8;base64,ZnVuY3Rpb24gR2V0Q3VycmVudFNlc3Npb25JZDogRFdPUkQ7CmFzbQogIG1vdiAgICAgZWF4LGZzOlskMDAwMDAwMThdOyAgIC8vIEdldCBURUIKICBtb3YgICAgIGVheCxbZWF4KyQzMF07ICAgICAgICAvLyBQUEVCCiAgbW92ICAgICBlYXgsW2VheCskMWQ0XTsgICAgICAgLy8gUEVCLlNlc3Npb25JZAplbmQ7"&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-objectpascal" data-lang="objectpascal"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;GetCurrentSessionId&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;DWORD&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;asm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;mov&lt;span class="w"&gt; &lt;/span&gt;eax&lt;span class="p"&gt;,&lt;/span&gt;fs&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;$00000018&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Get TEB&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;mov&lt;span class="w"&gt; &lt;/span&gt;eax&lt;span class="p"&gt;,[&lt;/span&gt;eax&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;$30&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// PPEB&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;mov&lt;span class="w"&gt; &lt;/span&gt;eax&lt;span class="p"&gt;,[&lt;/span&gt;eax&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;$1d4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// PEB.SessionId&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Get the Current Console Session Id:&lt;/p&gt;</description></item><item><title>Obtain Fully Qualified Domain Name from Netbios Domain Name</title><link>https://remkoweijnen.nl/blog/2010/06/17/obtain-fully-qualified-domain-name-from-netbios-domain-name/</link><pubDate>Thu, 17 Jun 2010 14:34:42 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/06/17/obtain-fully-qualified-domain-name-from-netbios-domain-name/</guid><description>&lt;p&gt;I needed to obtain the Fully Qualified Domain Name (FQDN) for a given NetBios domain name. Eg from MYDOMAIN to dc=mydomain,dc=local.&lt;/p&gt;
&lt;p&gt;I did some tests with the &lt;a href="http://msdn.microsoft.com/en-us/library/ms725484%28VS.85%29.aspx" target="_blank"&gt;TranslateName&lt;/a&gt; API and if you append a \ to the domain name it returns the FQDN.&lt;/p&gt;
&lt;p&gt;Here is a short example:&lt;/p&gt;</description></item><item><title>Having fun with Windows Licensing</title><link>https://remkoweijnen.nl/blog/2010/06/15/having-fun-with-windows-licensing/</link><pubDate>Tue, 15 Jun 2010 15:09:14 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/06/15/having-fun-with-windows-licensing/</guid><description>&lt;p&gt;If you look into the registry in the key HKLM\System\CurrentControlSet\ProductOptions you will find several licensing related Values.&lt;/p&gt;
&lt;p&gt;The ProductType and ProductSuite keys contain the OS Suite and Edition, but the ProductPolicy key is much more interesting. So let&amp;rsquo;s have a closer look at it, open RegEdit and DoubleClick the key, you will something like the screenshot below, a Binary Value:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2010/06/productpolicy1-1.webp" class="glightbox" data-type="image" data-gallery="post-588"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2010/06/productpolicy1-1-small.webp" alt="ProductPolicy1" width="215" height="188" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see the license names are there as a Unicode string and later on I will show you how we can read the values. But because I didn&amp;rsquo;t want to extract all the names manually I decided to see if I could reverse the used structure because it didn&amp;rsquo;t look very complicated. Using a Hex Editor I could determine the important part of the structure.&lt;/p&gt;</description></item><item><title>Memory Leaks when using the Virtual TreeView Component</title><link>https://remkoweijnen.nl/blog/2010/06/09/memory-leaks-when-using-virtual-treeview-component/</link><pubDate>Wed, 09 Jun 2010 09:50:49 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/06/09/memory-leaks-when-using-virtual-treeview-component/</guid><description>&lt;p&gt;Again a about post about using the &lt;a href="http://www.soft-gems.net/index.php?option=com_content&amp;amp;task=view&amp;amp;id=12&amp;amp;Itemid=33" target="_blank"&gt;Virtual TreeView component&lt;/a&gt; (did I mention it&amp;rsquo;s brilliant?), this time I will talk about memory leaks.&lt;/p&gt;
&lt;p&gt;I often use Records to hold the treedata, and usually the record holds some string data (eg a caption) and an (a reference to) an Interface or Object(List) that holds more data.&lt;/p&gt;
&lt;p&gt;If you are familiar with Virtual Tree then you know that you must can the NodeData in the OnFreeNode event.&lt;/p&gt;</description></item><item><title>Setting ChildCount in a Virtual Tree</title><link>https://remkoweijnen.nl/blog/2010/06/08/setting-childcount-in-a-virtual-tree/</link><pubDate>Tue, 08 Jun 2010 17:39:57 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/06/08/setting-childcount-in-a-virtual-tree/</guid><description>&lt;p&gt;When working with the &lt;a href="http://www.soft-gems.net/index.php?option=com_content&amp;amp;task=view&amp;amp;id=12&amp;amp;Itemid=33" target="_blank"&gt;Virtual TreeView component&lt;/a&gt; the most optimized way of adding (or removing child nodes is by changing the ChildCount.&lt;/p&gt;
&lt;p&gt;I often make the mistake of change the ChildCount of a Node using:&lt;/p&gt;
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;objectpascal&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".pas" href="data:text/plain;charset=utf-8;base64,Tm9kZV4uQ2hpbGRDb3VudCA6PSBDb3VudDs="&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-objectpascal" data-lang="objectpascal"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Node&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;ChildCount&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Count&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you look into the source you will see why this will not work, the proper way is:&lt;/p&gt;</description></item><item><title>Random Active Directory Notes #4</title><link>https://remkoweijnen.nl/blog/2010/03/30/random-active-directory-notes-4/</link><pubDate>Tue, 30 Mar 2010 15:04:51 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/03/30/random-active-directory-notes-4/</guid><description>&lt;p&gt;Previously I discussed IDirectoryObject, today I will show how to change a user&amp;rsquo;s password with IDirectoryObject.&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t find any documentation except a &lt;a href="http://support.microsoft.com/kb/269190" target="_self"&gt;kb article&lt;/a&gt; describing how to use pure ldap to do it. Of course I could have used IADsUser::SetPassword but I decided not to because of the following reasons:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;IADs interfaces are terribly slow (although for one use you probably wouldn't really notice).&lt;/li&gt;
	&lt;li&gt;IADsUser::SetPassword tries 3 different methods to set the password (ldap over ssl, kerberos and finally NetUserSetInfo) which makes it even slower (most domain controllers do not have an ssl certificate) and unpredictable.&lt;/li&gt;
&lt;/ul&gt;
All example code I found was .NET based using the .NET wrappers for Active Directory and seemed to be meant for use in Adam rather than full Active Directory (it set port number to 389 and password mode to cleartext).
&lt;p&gt;In the end it&amp;rsquo;s not very difficult but nonetheless it took me a while before I got it right.&lt;/p&gt;
&lt;p&gt;We can write to the unicodePwd attribute which wants the password as a double quoted unicode string. If you look at this attribute with AdsiEdit you&amp;rsquo;ll see that the type is Octet String and that it can be written only.&lt;/p&gt;
&lt;p&gt;I was tricked with Delphi&amp;rsquo;s QuotedStr function for a while because it doesn&amp;rsquo;t return a double but single quoted string ;-)&lt;/p&gt;
&lt;p&gt;Below a small snippet from the upcoming JwsclActiveDirectory that shows how to use it:&lt;/p&gt;</description></item><item><title>Using Windows Resource Strings</title><link>https://remkoweijnen.nl/blog/2010/03/28/using-windows-resource-strings/</link><pubDate>Sun, 28 Mar 2010 10:45:05 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/03/28/using-windows-resource-strings/</guid><description>&lt;p&gt;A few days ago I wrote about Using &lt;a href="https://remkoweijnen.nl/blog/2010/03/24/using-windows-dialogs-from-delphi/" target="_blank"&gt;Windows Dialogs&lt;/a&gt; in your own programs, wouldn&amp;rsquo;t it be nice to be able to use Windows Resource Strings for the same reasons?&lt;/p&gt;
&lt;p&gt;Loading a resource string is not difficult, let&amp;rsquo;s look at some examples:&lt;/p&gt;</description></item><item><title>Using Windows Dialogs from Delphi</title><link>https://remkoweijnen.nl/blog/2010/03/24/using-windows-dialogs-from-delphi/</link><pubDate>Wed, 24 Mar 2010 11:48:41 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/03/24/using-windows-dialogs-from-delphi/</guid><description>&lt;p&gt;Today I reused a unit I wrote a long time ago for TSAdminEx that shows Resource Dialogs from DLL&amp;rsquo;s or Executables. I wrote it for a couple of reasons:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Reusing existing dialogs is conventient since the user already knows it.&lt;/li&gt;
	&lt;li&gt;Windows takes care of translating it into the user's language.&lt;/li&gt;
	&lt;li&gt;I am too lazy to recreate them ;-)&lt;/li&gt;
&lt;/ul&gt;
The code is hardly rocket science and could probably be improved and made more sophisticated but it works for me. I decided to share it since you may find it usefull.
&lt;p&gt;Here is a small usage example that shows the Reset Password dialog from Active Directory Users &amp;amp; Computers. This dialog is in dsadmin.dll (on Windows Vista/7 you will find it in ds.admin.dll.mui in the language subfolder eg %systemroot%\system32\en-US but you can load it using just the dll name).&lt;/p&gt;
&lt;p&gt;It looks like this:&lt;/p&gt;
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;c&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".c" href="data:text/plain;charset=utf-8;base64,MjE1IERJQUxPR0VYIDAsIDAsIDI1MiwgMTM5ClNUWUxFIERTX01PREFMRlJBTUUgfCBEU19DT05URVhUSEVMUCB8IFdTX1BPUFVQIHwgV1NfQ0FQVElPTiB8IFdTX1NZU01FTlUKRVhTVFlMRSBXU19FWF9DT05URVhUSEVMUApDQVBUSU9OICJSZXNldCBQYXNzd29yZCIKTEFOR1VBR0UgTEFOR19FTkdMSVNILCBTVUJMQU5HX0VOR0xJU0hfVVMKRk9OVCA4LCAiTVMgU2hlbGwgRGxnIgp7CiAgIENPTlRST0wgIiZOZXcgcGFzc3dvcmQ6IiwgLTEsIFNUQVRJQywgU1NfTEVGVCB8IFdTX0NISUxEIHwgV1NfVklTSUJMRSB8IFdTX0dST1VQLCA3LCAxMCwgNzksIDEwCiAgIENPTlRST0wgIiIsIDIyMCwgRURJVCwgRVNfTEVGVCB8IEVTX1BBU1NXT1JEIHwgRVNfQVVUT0hTQ1JPTEwgfCBXU19DSElMRCB8IFdTX1ZJU0lCTEUgfCBXU19CT1JERVIgfCBXU19UQUJTVE9QLCA5MiwgNywgMTUzLCAxNAogICBDT05UUk9MICImQ29uZmlybSBwYXNzd29yZDoiLCAtMSwgU1RBVElDLCBTU19MRUZUIHwgV1NfQ0hJTEQgfCBXU19WSVNJQkxFIHwgV1NfR1JPVVAsIDcsIDI4LCA3OSwgMTAKICAgQ09OVFJPTCAiIiwgMjIyLCBFRElULCBFU19MRUZUIHwgRVNfUEFTU1dPUkQgfCBFU19BVVRPSFNDUk9MTCB8IFdTX0NISUxEIHwgV1NfVklTSUJMRSB8IFdTX0JPUkRFUiB8IFdTX1RBQlNUT1AsIDkyLCAyNSwgMTUzLCAxNAogICBDT05UUk9MICImVXNlciBtdXN0IGNoYW5nZSBwYXNzd29yZCBhdCBuZXh0IGxvZ29uIiwgMjYxLCBCVVRUT04sIEJTX0FVVE9DSEVDS0JPWCB8IEJTX0xFRlQgfCBCU19UT1AgfCBCU19NVUxUSUxJTkUgfCBXU19DSElMRCB8IFdTX1ZJU0lCTEUgfCBXU19UQUJTVE9QLCA3LCA0NiwgMjM3LCAxMAogICBDT05UUk9MICJUaGUgdXNlciBtdXN0IGxvZ29mZiBhbmQgdGhlbiBsb2dvbiBhZ2FpbiBmb3IgdGhlIGNoYW5nZSB0byB0YWtlIGVmZmVjdC4iLCAtMSwgU1RBVElDLCBTU19MRUZUIHwgV1NfQ0hJTEQgfCBXU19WSVNJQkxFIHwgV1NfR1JPVVAsIDE0LCA2MSwgMjMxLCA4CiAgIENPTlRST0wgIiIsIDgzMjcsIFNUQVRJQywgU1NfTEVGVCB8IFdTX0NISUxEIHwgV1NfVklTSUJMRSB8IFdTX0dST1VQLCA3LCA3NiwgMjM4LCAxNgogICBDT05UUk9MICJVbmxvY2sgdGhlIHVzZXIncyAmYWNjb3VudCIsIDgzMjgsIEJVVFRPTiwgQlNfQVVUT0NIRUNLQk9YIHwgQlNfTEVGVCB8IEJTX1RPUCB8IEJTX01VTFRJTElORSB8IFdTX0NISUxEIHwgV1NfVklTSUJMRSB8IFdTX1RBQlNUT1AsIDE0LCA5NiwgMjMwLCAxMAogICBDT05UUk9MICJPSyIsIDEsIEJVVFRPTiwgQlNfREVGUFVTSEJVVFRPTiB8IFdTX0NISUxEIHwgV1NfVklTSUJMRSB8IFdTX1RBQlNUT1AsIDE0MCwgMTE4LCA1MCwgMTQKICAgQ09OVFJPTCAiQ2FuY2VsIiwgMiwgQlVUVE9OLCBCU19QVVNIQlVUVE9OIHwgV1NfQ0hJTEQgfCBXU19WSVNJQkxFIHwgV1NfVEFCU1RPUCwgMTk1LCAxMTgsIDUwLCAxNAp9"&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="mi"&gt;215&lt;/span&gt; &lt;span class="n"&gt;DIALOGEX&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;252&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;139&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;STYLE&lt;/span&gt; &lt;span class="n"&gt;DS_MODALFRAME&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;DS_CONTEXTHELP&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_POPUP&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CAPTION&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_SYSMENU&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;EXSTYLE&lt;/span&gt; &lt;span class="n"&gt;WS_EX_CONTEXTHELP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;CAPTION&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Reset Password&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;LANGUAGE&lt;/span&gt; &lt;span class="n"&gt;LANG_ENGLISH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SUBLANG_ENGLISH_US&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;FONT&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;MS Shell Dlg&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CONTROL&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;amp;New password:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;STATIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SS_LEFT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CHILD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_VISIBLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_GROUP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;79&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CONTROL&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;220&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EDIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ES_LEFT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ES_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ES_AUTOHSCROLL&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CHILD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_VISIBLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_BORDER&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_TABSTOP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;92&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;153&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CONTROL&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;amp;Confirm password:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;STATIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SS_LEFT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CHILD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_VISIBLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_GROUP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;79&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CONTROL&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;222&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EDIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ES_LEFT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ES_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ES_AUTOHSCROLL&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CHILD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_VISIBLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_BORDER&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_TABSTOP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;92&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;153&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CONTROL&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;amp;User must change password at next logon&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;261&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BUTTON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BS_AUTOCHECKBOX&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BS_LEFT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BS_TOP&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BS_MULTILINE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CHILD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_VISIBLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_TABSTOP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;237&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CONTROL&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;The user must logoff and then logon again for the change to take effect.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;STATIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SS_LEFT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CHILD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_VISIBLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_GROUP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;61&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;231&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CONTROL&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8327&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;STATIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SS_LEFT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CHILD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_VISIBLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_GROUP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;76&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;238&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CONTROL&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Unlock the user&amp;#39;s &amp;amp;account&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8328&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BUTTON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BS_AUTOCHECKBOX&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BS_LEFT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BS_TOP&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;BS_MULTILINE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CHILD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_VISIBLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_TABSTOP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;96&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;230&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CONTROL&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;OK&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BUTTON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BS_DEFPUSHBUTTON&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CHILD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_VISIBLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_TABSTOP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;140&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;118&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CONTROL&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Cancel&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BUTTON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BS_PUSHBUTTON&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_CHILD&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_VISIBLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;WS_TABSTOP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;195&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;118&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Random Active Directory Notes #3</title><link>https://remkoweijnen.nl/blog/2010/03/22/random-active-directory-notes-3/</link><pubDate>Mon, 22 Mar 2010 22:57:30 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/03/22/random-active-directory-notes-3/</guid><description>&lt;p&gt;Last time I talked briefly about IDirectoryObject and IDirectorySearch, let&amp;rsquo;s go into a little more detail today.&lt;/p&gt;
&lt;p&gt;IDirectoryObject is an Interface that we can use to query anything in Active Directory, users, groups, organizational units, containers and so on.&lt;/p&gt;
&lt;p&gt;I thought the best explanation would be to build a very small sample project, so let&amp;rsquo;s do that!&lt;/p&gt;
&lt;p&gt;First we need some units, so please add the following units to your uses clause:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;ComObj (for EOleException and it calls CoInitialize for us)&lt;/li&gt;
	&lt;li&gt;JwaWindows for the proper Adsi declarations&lt;/li&gt;
&lt;/ul&gt;
Next declare the following types:
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;objectpascal&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".pas" href="data:text/plain;charset=utf-8;base64,dHlwZQogIC8vIEZvciBEZWxwaGkgPCAyMDA5IHVzZSBXaWRlU3RyaW5nCiAgVVN0cmluZyA9IHskSUZERUYgVU5JQ09ERX1Vbmljb2RlU3RyaW5neyRFTFNFfVdpZGVTdHJpbmd7JEVORElGfTsKCiAgLy8gQXJyYXkgb2YgQURTX0FUVFJfSU5GTyByZWNvcmRzCiAgVEFkc0F0dHJJbmZvQXJyYXkgPSBhcnJheVswLi5BTllTSVpFX0FSUkFZLTFdIG9mIEFEU19BVFRSX0lORk87CiAgUEFkc0F0dHJJbmZvQXJyYXkgPSBeVEFkc0F0dHJJbmZvQXJyYXk7"&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-objectpascal" data-lang="objectpascal"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;type&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// For Delphi &amp;lt; 2009 use WideString&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;UString&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;{$IFDEF UNICODE}&lt;/span&gt;&lt;span class="kt"&gt;UnicodeString&lt;/span&gt;&lt;span class="cp"&gt;{$ELSE}&lt;/span&gt;&lt;span class="kt"&gt;WideString&lt;/span&gt;&lt;span class="cp"&gt;{$ENDIF}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Array of ADS_ATTR_INFO records&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;TAdsAttrInfoArray&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;ANYSIZE_ARRAY&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ADS_ATTR_INFO&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;PAdsAttrInfoArray&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;TAdsAttrInfoArray&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Random Active Directory Notes #2</title><link>https://remkoweijnen.nl/blog/2010/03/12/random-active-directory-notes-2/</link><pubDate>Fri, 12 Mar 2010 16:57:32 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/03/12/random-active-directory-notes-2/</guid><description>&lt;p&gt;If you have ever used Adsi you have probably used the &lt;a href="http://msdn.microsoft.com/en-us/library/aa705950%28VS.85%29.aspx" target="_blank"&gt;IADs&lt;/a&gt; interface or derived interfaces such as &lt;a href="http://msdn.microsoft.com/en-us/library/aa746340%28VS.85%29.aspx" target="_blank"&gt;IADsUser&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/aa706021%28VS.85%29.aspx" target="_blank"&gt;IADsGroup&lt;/a&gt; (maybe even without realising this).&lt;/p&gt;
&lt;p&gt;What you need to know is that these interfaces were created to support scripting languages such as VBScript. The reason is that these scripting language have no support at all for structures such as ADSVALUE and don&amp;rsquo;t work with Pointers.&lt;/p&gt;</description></item><item><title>Random Active Directory Notes</title><link>https://remkoweijnen.nl/blog/2010/03/10/random-active-directory-notes/</link><pubDate>Wed, 10 Mar 2010 11:19:29 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/03/10/random-active-directory-notes/</guid><description>&lt;p&gt;I am working on an Customer Management Console that will present all adminstrative tasks that customers will need in their environment in a single console.&lt;/p&gt;
&lt;p&gt;It will handle Active Directory, Terminal Server and Citrix, Printers and will offer specific Views and Reporting. For the Active Directory stuff I decided to create some classes that enabled me to work with AD in a more Delphi OOP way.&lt;/p&gt;</description></item><item><title>Random Active Directory Notes #1</title><link>https://remkoweijnen.nl/blog/2010/03/10/random-active-directory-notes-1/</link><pubDate>Wed, 10 Mar 2010 11:11:13 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/03/10/random-active-directory-notes-1/</guid><description>&lt;p&gt;If you are going to use the Active Directory Service Interface (ADSI) in Delphi, the first thing you will need is the typelibrary (TLB). This TLB is in the windows\system32 folder and has the name activeds.tlb.&lt;/p&gt;
&lt;p&gt;We can import this tlb in Delphi (the procedure differs somewhat, depending on the Delphi version), but there are quite some problems with the resulting pas file of this import:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Ugly and non meaningfull names such as __MIDL___MIDL_itf_ads_0000_0000_001.&lt;/li&gt;
	&lt;li&gt;Record sizes are sometimes (read: usually) wrong due to alignment errors.&lt;/li&gt;
	&lt;li&gt;Some Interfaces have wrong declarations resulting in Access Violations or just hard to use (eg using var for input parameters).&lt;/li&gt;
	&lt;li&gt;Delphi works with Typed Pointer but since it has no clue on the proper name it uses PUserTypexx (eg PUserType1 = ^_ADS_CASEIGNORE_LIST). It's hard to recognise later on what the real type is.&lt;/li&gt;
&lt;/ul&gt;
A version of the imported tlb is also in the Jedi Apilib (JwaAdsTLB) and basically it had the same errors. Because I was wondering how this would work in c++ I checked the SDK and found the header file Iads.h.</description></item><item><title>Did you make a SasLibEx enquiry? And... news!</title><link>https://remkoweijnen.nl/blog/2010/02/22/did-you-make-a-saslibex-enquiry-and-news/</link><pubDate>Mon, 22 Feb 2010 14:07:28 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2010/02/22/did-you-make-a-saslibex-enquiry-and-news/</guid><description>&lt;p&gt;My hoster has had some problems with the simulatesas.com domain that I use for SasLibEx enquiries. If you have sent mail to &lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2010/02/mail-2.gif" alt="mail" width="147" height="15" /&gt; that has not been answered I kindly request you to send it again.&lt;/p&gt;
&lt;p&gt;I would also like to briefly tell you about an upcoming new release of SasLib, version 2.0. There is so much I would like to tell you about it but I will limit it to a few highlights here and save the rest for the upcoming website on &lt;a href="http://www.simulatesas.com"&gt;SimulateSAS.com&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Small LaunchRDP Update</title><link>https://remkoweijnen.nl/blog/2009/11/06/small-launchrdp-update/</link><pubDate>Fri, 06 Nov 2009 22:44:27 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/11/06/small-launchrdp-update/</guid><description>&lt;p&gt;For a long time now people have asked for a version of &lt;a href="https://remkoweijnen.nl/blog/2007/10/17/launch-rdp-from-commandline/"&gt;LaunchRDP&lt;/a&gt; that includes the Connection Bar. The original version was originally written for a very specific purpose and I never anticipated so many people would want to use it. But it seems that a lot of people like the Connection Bar (I hate it, especially with sessions in sessions, so that&amp;rsquo;s why I am using &lt;a href="https://remkoweijnen.nl/blog/2008/11/02/rdp-session-with-local-taskbar-visible/"&gt;RDPWithLocalTaskbar&lt;/a&gt;).&lt;/p&gt;</description></item><item><title>Windows Installer proxy information not correctly registered</title><link>https://remkoweijnen.nl/blog/2009/11/05/windows-installer-proxy-information-not-correctly-registered/</link><pubDate>Thu, 05 Nov 2009 22:11:06 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/11/05/windows-installer-proxy-information-not-correctly-registered/</guid><description>&lt;p&gt;I was deploying an unattended installation of Citrix XenApp 5.0 with Altiris Deployment Server. The installation consists of several prerequisites, the installation of XenApp and finally the Citrix Management Consoles.&lt;/p&gt;
&lt;p&gt;The installation is performed with a special account and not the Local System account because the install packages are located on the network.&lt;/p&gt;
&lt;p&gt;When testing the deployment on a Windows Server 2008 I noticed that sometimes MSI based installations would fail with error code 1603 or 1601.&lt;/p&gt;</description></item><item><title>SasLibEx updates</title><link>https://remkoweijnen.nl/blog/2009/04/07/saslibex-updates/</link><pubDate>Tue, 07 Apr 2009 08:40:36 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/04/07/saslibex-updates/</guid><description>&lt;p&gt;I have found and tested some new functionalities which I will add to &lt;a href="https://remkoweijnen.nl/blog/2009/03/30/sending-ctrl-alt-del-simulate-sas-in-windows-vista/"&gt;SasLibEx&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Unlocking workstation without entering password&lt;/li&gt;
	&lt;li&gt;Cancel UAC (User Account Control) request&lt;/li&gt;
	&lt;li&gt;fully disable Ctrl-Alt-Del&lt;/li&gt;
	&lt;li&gt;Cancel Ctrl-Alt-Del&lt;/li&gt;
	&lt;li&gt;Switch between secure desktop (where the UAC prompt is) and the normal desktop.&lt;/li&gt;
&lt;/ul&gt;
Some people asked if SasLibEx works on x64 or Windows 7, the answer is yes. I tested on build 7000 of Windows 7 beta and also on Server 2008 x64.
&lt;section class="comments"&gt;
&lt;h2&gt;5 Comments&lt;/h2&gt;
&lt;ol class="comment-list"&gt;
&lt;li class="comment depth-0"&gt;&lt;div class="comment-meta"&gt;&lt;span class="comment-author"&gt;&lt;a href="https://remkoweijnen.nl/blog/2009/03/30/sending-ctrl-alt-del-simulate-sas-in-windows-vista/" rel="nofollow ugc"&gt;Simulate ctrl-alt-del in Windows Vista | RemkoWeijnen.nl&lt;/a&gt;&lt;/span&gt; &lt;time datetime="2009-05-18"&gt;May 18, 2009&lt;/time&gt;&lt;/div&gt;&lt;div class="comment-body"&gt;&lt;p&gt;[...] SasLibEx updates | RemkoWeijnen.nl April 7th, 2009 at 8:41 2 [...]&lt;/p&gt;</description></item><item><title>Sending WM_KEYDOWN or WM_KEYUP</title><link>https://remkoweijnen.nl/blog/2009/03/30/sending-wm_keydown-or-wm_keyup/</link><pubDate>Mon, 30 Mar 2009 22:57:28 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/03/30/sending-wm_keydown-or-wm_keyup/</guid><description>&lt;p&gt;If you read the MSDN documentation of &lt;a href="http://msdn.microsoft.com/en-us/library/ms646280(VS.85).aspx" target="_blank"&gt;WM_KEYDOWN&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/ms646281(VS.85).aspx" target="_blank"&gt;WM_KEYUP&lt;/a&gt; you can see that those message require us to interpret lParam as a bitfield:&lt;/p&gt;
&lt;blockquote&gt;lParam
Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table.
&lt;p&gt;0-15&lt;br&gt;
Specifies the repeat count for the current message. The value is the number of times the keystroke is autorepeated as a result of the user holding down the key. The repeat count is always one for a WM_KEYUP message.&lt;br&gt;
16-23&lt;br&gt;
Specifies the scan code. The value depends on the OEM.&lt;br&gt;
24&lt;br&gt;
Specifies whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.&lt;br&gt;
25-28&lt;br&gt;
Reserved; do not use.&lt;br&gt;
29&lt;br&gt;
Specifies the context code. The value is always 0 for a WM_KEYUP message.&lt;br&gt;
30&lt;br&gt;
Specifies the previous key state. The value is always 1 for a WM_KEYUP message.&lt;br&gt;
31&lt;br&gt;
Specifies the transition state. The value is always 1 for a WM_KEYUP message.&lt;/blockquote&gt;&lt;br&gt;
I was looking for a convenient way to get and read the bits and this is what I made up:&lt;/p&gt;</description></item><item><title>Sending Ctrl-Alt-Del / Simulate SAS in Windows Vista</title><link>https://remkoweijnen.nl/blog/2009/03/30/sending-ctrl-alt-del-simulate-sas-in-windows-vista/</link><pubDate>Mon, 30 Mar 2009 21:51:48 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/03/30/sending-ctrl-alt-del-simulate-sas-in-windows-vista/</guid><description>&lt;p&gt;Existing &lt;a href="https://remkoweijnen.nl/blog/2008/12/13/locking-a-workstation-part-1/"&gt;code&lt;/a&gt; to simulate the Secure Attention Sequence (SAS),which most people refer to as control alt delete or ctrl-alt-del, no longer works in Windows Vista. It seems that Microsoft offers a library that exports a function called SimulateSAS(). It is not public and one is supposed to request it by sending a mail to &lt;a href="mailto:saslib@microsoft.com"&gt;&lt;a href="mailto:saslib@microsoft.com"&gt;saslib@microsoft.com&lt;/a&gt;&lt;/a&gt;. Mails to this address remain unanswered though.&lt;/p&gt;</description></item><item><title>Reading physical memory size from the registry</title><link>https://remkoweijnen.nl/blog/2009/03/20/reading-physical-memory-size-from-the-registry/</link><pubDate>Fri, 20 Mar 2009 13:15:46 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/03/20/reading-physical-memory-size-from-the-registry/</guid><description>&lt;p&gt;I&amp;rsquo;m working on a new build of &lt;a href="https://remkoweijnen.nl/blog/2009/02/20/tsadminex-beta-release/"&gt;TSAdminEx&lt;/a&gt; for which I need to query the total amount of physical memory. Locally we can use the &lt;a href="http://msdn.microsoft.com/en-us/library/aa366589(VS.85).aspx" target="_blank"&gt;GlobalMemoryStatusEx&lt;/a&gt; API but there&amp;rsquo;s no API to do this remotely. It would be possible using WMI but I decided not to use that because I dislike it because of it&amp;rsquo;s slowness and I need support for older OS versions which might not have WMI.&lt;/p&gt;
&lt;p&gt;So I found in the registry the following key:&lt;/p&gt;
&lt;blockquote&gt;HKLM\HARDWARE\RESOURCEMAP\System Resources\Physical Memory&lt;/blockquote&gt;
It has a value .Translated of type RES_RESOURCE_LIST which seems undocumented besides stating that it exists. Regedit knows how to handle it though. If you doubleclick on the key you will see something like this:</description></item><item><title>TSAdminEx Features Part 3</title><link>https://remkoweijnen.nl/blog/2009/02/25/tsadminex-features-part-3/</link><pubDate>Wed, 25 Feb 2009 13:08:31 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/02/25/tsadminex-features-part-3/</guid><description>&lt;table border="0" cellpadding="3" cellspacing="3" width="100%"&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://remkoweijnen.nl/blog/2009/02/20/tsadminex-beta-release/"&gt;Beta Release&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://remkoweijnen.nl/blog/2009/02/23/tsadminex-features-part-1/"&gt;Part 1&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://remkoweijnen.nl/blog/2009/02/24/tsadminex-features-part-2/"&gt;Part 2&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
This is part 3 of the TSAdminEx Features series. Today I will discuss the Process View. As usual we will start by comparing TSAdmin to TSAdminEx again. So let's look at TSAdmin Process View:
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadminprocess.webp" class="glightbox" data-type="image" data-gallery="post-320"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadminprocess-small.webp" alt="TSAdminProcess" height="279" width="430" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And the one from TSAdminEx:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadminexprocessview.webp" class="glightbox" data-type="image" data-gallery="post-320"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadminexprocessview-small.webp" alt="TSAdminExProcessView" height="182" width="430" /&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>TSAdminEx Features Part 2</title><link>https://remkoweijnen.nl/blog/2009/02/24/tsadminex-features-part-2/</link><pubDate>Tue, 24 Feb 2009 10:17:07 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/02/24/tsadminex-features-part-2/</guid><description>&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/2009/02/23/tsadminex-features-part-1"&gt;Part1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now that a &lt;a href="https://remkoweijnen.nl/blog/2009/02/20/tsadminex-beta-release/"&gt;TSAdminEx beta is ready&lt;/a&gt; I will be showing you some features. In this part I will show the Sessions View.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start again with a compare of TSAdmin and TSAdminEx:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadminsessionview.webp" class="glightbox" data-type="image" data-gallery="post-290"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadminsessionview-small.webp" alt="TSAdminSessionView" height="177" width="430" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadminexsessionview.webp" class="glightbox" data-type="image" data-gallery="post-290"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadminexsessionview-small.webp" alt="TSAdminExSessionView" height="135" width="430" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see TSAdminEx shows more details, it shows the following extra columns:&lt;/p&gt;</description></item><item><title>TSAdminEx Features Part 1</title><link>https://remkoweijnen.nl/blog/2009/02/23/tsadminex-features-part-1/</link><pubDate>Mon, 23 Feb 2009 16:18:28 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/02/23/tsadminex-features-part-1/</guid><description>&lt;p align="right"&gt;&lt;a href="https://remkoweijnen.nl/blog/2009/02/24/tsadminex-features-part-2/"&gt;Part 2&lt;/a&gt;&lt;/p&gt;
Now that a &lt;a href="https://remkoweijnen.nl/blog/2009/02/20/tsadminex-beta-release/" target="_blank"&gt;TSAdminEx beta is ready&lt;/a&gt; I will be showing you some features. In this part 1 I will be comparing the Users view to TSAdmin.
&lt;p&gt;Let&amp;rsquo;s start TSAdmin, this tool is present by default on Windows 2003. If you use Windows XP or Windows Vista you can get it by installing the &lt;a href="http://www.petri.co.il/download_windows_2003_r2_adminpak.htm" target="_blank"&gt;Administration Pack&lt;/a&gt;. Please note that TSAdmin does not work on Vista RTM due to a &lt;a href="https://remkoweijnen.nl/blog/2007/12/19/why-tsadmin-crashes-on-windows-vista/" target="_blank"&gt;bug&lt;/a&gt; that was &lt;a href="https://remkoweijnen.nl/blog/2008/03/02/vista-sp1-changes-to-terminal-server-api/" target="_blank"&gt;corrected in Vista SP1&lt;/a&gt; (TSAdminEx works fine on both RTM as well as SP1)&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadmin1.webp" class="glightbox" data-type="image" data-gallery="post-264"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadmin1-small.webp" alt="TSAdmin1" height="159" width="430" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s open TSAdminEx and start comparing&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadminex1.webp" class="glightbox" data-type="image" data-gallery="post-264"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/tsadminex1-small.webp" alt="TSAdminEx1" height="156" width="430" /&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>TSAdminEx Beta release</title><link>https://remkoweijnen.nl/blog/2009/02/20/tsadminex-beta-release/</link><pubDate>Fri, 20 Feb 2009 17:59:06 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/02/20/tsadminex-beta-release/</guid><description>&lt;p&gt;Over the last months I have been working hard on TSAdminEx and now, finally, I can now present a first beta release.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t know what TSAdminEx is let me briefly introduce it. TSAdminEx is a tool that combines functionality of several existing tools: it has the power of task manager combined with the details of Process Explorer and the Terminal Server support of TSAdmin. On top of that it fully supports remote systems out of the box without installing any agents or services. It also has some unique features that neither of the mentioned tools can do!&lt;/p&gt;
&lt;p&gt;Several new features have been implemented since the &lt;a href="https://remkoweijnen.nl/blog/2008/01/27/test-2/" target="_blank"&gt;last time I talked about TSAdminEx&lt;/a&gt; and I will show you the most exciting ones here:&lt;/p&gt;</description></item><item><title>Accessing kernel objects in other sessions part 2</title><link>https://remkoweijnen.nl/blog/2009/02/03/accessing-kernel-objects-in-other-sessions-part-2/</link><pubDate>Tue, 03 Feb 2009 14:36:53 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/02/03/accessing-kernel-objects-in-other-sessions-part-2/</guid><description>&lt;p&gt;In &lt;a href="https://remkoweijnen.nl/blog/2009/01/27/accessing-kernel-objects-in-other-sessions/"&gt;part 1&lt;/a&gt; I showed how to create and open objects in Terminal Server Sessions. However, these are not all of the possible places where you can place objects via documented kernel32.dll functions.&lt;/p&gt;
&lt;p&gt;If we look into Winobj again, we notice, that every &lt;strong&gt;BaseNamedObjects&lt;/strong&gt; directory has a subdirectory named &lt;strong&gt;Restricted&lt;/strong&gt;. To be honest, I do not know why it&amp;rsquo;s created; it&amp;rsquo;s security allows object creation for &lt;em&gt;LocalSystem&lt;/em&gt; and &lt;em&gt;RESTRICTED&lt;/em&gt; special user (in windows 2000, &lt;em&gt;Everyone&lt;/em&gt; can also create objects in it). So, we can use it as prefix for object creation, for example, &lt;strong&gt;Restricted\MyAppEvent&lt;/strong&gt;: &lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/restrictedobject.gif" class="glightbox" data-type="image" data-gallery="post-242"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2009/02/restrictedobject-small.gif" alt="RestrictedObject" height="291" width="430" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Of course, you can still use &lt;strong&gt;Global&lt;/strong&gt;, &lt;strong&gt;Local&lt;/strong&gt;, or &lt;strong&gt;Session&lt;/strong&gt; links&lt;/p&gt;</description></item><item><title>Accessing kernel objects in other sessions part 1</title><link>https://remkoweijnen.nl/blog/2009/01/27/accessing-kernel-objects-in-other-sessions/</link><pubDate>Tue, 27 Jan 2009 19:43:52 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2009/01/27/accessing-kernel-objects-in-other-sessions/</guid><description>&lt;p&gt;As you know, many &lt;em&gt;kernel32.dll&lt;/em&gt; functions, which are working with named objects, like &lt;em&gt;OpenEvent&lt;/em&gt;, can be used to work with global and local objects. So what are global and local objects? Global objects are created in session 0 and are actually located in the &lt;strong&gt;\BaseNamedObjects&lt;/strong&gt; directory, while local objects are created in the caller&amp;rsquo;s session (for example in the &lt;strong&gt;\Sessions\5\BaseNamedObjects&lt;/strong&gt; directory (for session 0, global and local has no meaning since they point to the same object)). MSDN says that you can access only the objects in your own session(via the &lt;strong&gt;Local&amp;lt;/strong&amp;gt; prefix) and in session 0 (via the &lt;strong&gt;Global&amp;lt;/strong&amp;gt; prefix). But what if you need to access an object in another session?&lt;/p&gt;</description></item><item><title>Locking a workstation - part 2</title><link>https://remkoweijnen.nl/blog/2008/12/23/locking-a-workstation-part-2/</link><pubDate>Tue, 23 Dec 2008 17:13:37 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/12/23/locking-a-workstation-part-2/</guid><description>&lt;p&gt;In &lt;a href="https://remkoweijnen.nl/blog/2008/12/13/locking-a-workstation-part-1/"&gt;part 1&lt;/a&gt; I showed how &lt;em&gt;winlogon.exe&lt;/em&gt; registers its process and main window handle.&lt;/p&gt;
&lt;p&gt;In the &lt;em&gt;SasCreate&lt;/em&gt; function, winlogon.exe registers hotkeys like this:&lt;/p&gt;
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;objectpascal&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".pas" href="data:text/plain;charset=utf-8;base64,Y29uc3QKICBNT0RfU0FTID0gJDgwMDA7CgogIFJlZ2lzdGVySG90S2V5KFNhc1dpbmRvdywgMCwgTU9EX1NBUyBvciBNT0RfQ09OVFJPTCBvciBNT0RfQUxULCBWS19ERUxFVEUpOwoKeyRJRkRFRiBDSEVDS0VEX0JVSUxEfQogIFJlZ2lzdGVySG90S2V5KFNhc1dpbmRvdywgMSwgTU9EX0FMVCBvciBNT0RfQ09OVFJPTCBvciBNT0RfU0hJRlQsIFZLX0RFTEVURSk7IC8vIGhhbmRsZXIganVzdCBjYWxscyBOdFNodXRkb3duU3lzdGVtCiAgaWYgRW5hYmxlRGVza3RvcFN3aXRjaGluZyB0aGVuCiAgICBSZWdpc3RlckhvdEtleShTYXNXaW5kb3csIDIsIE1PRF9BTFQgb3IgTU9EX0NPTlRST0wsIFZLX1RBQik7IC8vIGhhbmRsZXIgc3dpdGNoZXMgZGVmYXVsdCBhbmQgd2lubG9nb24gZGVza3RvcHMKICBpZiBXaW5sb2dvbkluZm9MZXZlbEZsYWcgdGhlbgogICAgUmVnaXN0ZXJIb3RrZXkoU2FzV2luZG93LCAzLCBNT0RfQUxUIG9yIE1PRF9DT05UUk9MIG9yIE1PRF9TSElGVCwgVktfVEFCKTsgLy8gaGFuZGxlciBqdXN0IGNhbGxzIERlYnVnQnJlYWsKeyRFTkRJRn0KCiAgUmVnaXN0ZXJIb3RLZXkoU2FzV2luZG93LCA0LCBNT0RfQ09OVFJPTCBvciBNT0RfU0hJRlQsIFZLX0VTQ0FQRSk7IC8vIGhhbmRsZXIgZXhlY3V0ZXMgdGFzayBtYW5hZ2VyCnskSUZERUYgV0lOWFBfT1JfTEFURVJ9CiAgUmVnaXN0ZXJIb3RLZXkoU2FzV2luZG93LCA1LCBNT0RfV0lOLCBCeXRlKCdMJyk7IC8vIGhhbmRsZXIgbG9ja3MgdGhlIHdvcmtzdGF0aW9uCiAgUmVnaXN0ZXJIb3RrZXkoU2FzV2luZG93LCA2LCBNT0RfV0lOLCBCeXRlKCdVJyk7IC8vIGhhbmRsZXIgZXhlY3V0ZXMgdXRpbG1hbiBvbiBjdXJyZW50IGRlc2t0b3AKeyRFTkRJRn0="&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-objectpascal" data-lang="objectpascal"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_SAS&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;$8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;RegisterHotKey&lt;span class="o"&gt;(&lt;/span&gt;SasWindow&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_SAS&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_CONTROL&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_ALT&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;VK_DELETE&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;{$IFDEF CHECKED_BUILD}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;RegisterHotKey&lt;span class="o"&gt;(&lt;/span&gt;SasWindow&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_ALT&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_CONTROL&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_SHIFT&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;VK_DELETE&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// handler just calls NtShutdownSystem&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;EnableDesktopSwitching&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;RegisterHotKey&lt;span class="o"&gt;(&lt;/span&gt;SasWindow&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_ALT&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_CONTROL&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;VK_TAB&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// handler switches default and winlogon desktops&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;WinlogonInfoLevelFlag&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;RegisterHotkey&lt;span class="o"&gt;(&lt;/span&gt;SasWindow&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_ALT&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_CONTROL&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_SHIFT&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;VK_TAB&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// handler just calls DebugBreak&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;{$ENDIF}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;RegisterHotKey&lt;span class="o"&gt;(&lt;/span&gt;SasWindow&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_CONTROL&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_SHIFT&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;VK_ESCAPE&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// handler executes task manager&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;{$IFDEF WINXP_OR_LATER}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;RegisterHotKey&lt;span class="o"&gt;(&lt;/span&gt;SasWindow&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_WIN&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Byte&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;L&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// handler locks the workstation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;RegisterHotkey&lt;span class="o"&gt;(&lt;/span&gt;SasWindow&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;MOD_WIN&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Byte&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;U&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// handler executes utilman on current desktop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;{$ENDIF}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Did you notice the MOD_SAS constant?&lt;/p&gt;</description></item><item><title>Locking a workstation - part 1</title><link>https://remkoweijnen.nl/blog/2008/12/13/locking-a-workstation-part-1/</link><pubDate>Sat, 13 Dec 2008 23:13:08 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/12/13/locking-a-workstation-part-1/</guid><description>&lt;p&gt;Win32 API provides only 1 function for locking workstation, named &lt;strong&gt;LockWorkstation&lt;/strong&gt;. What does it do and how we can use it?&lt;/p&gt;
&lt;p&gt;When a new session is started, &lt;em&gt;smss.exe&lt;/em&gt; invokes &lt;em&gt;winlogon.exe&lt;/em&gt;. It registers its process id in &lt;em&gt;win32k.sys&lt;/em&gt; by calling &lt;strong&gt;RegisterLogonProcess&lt;/strong&gt;. It has this prototype:&lt;/p&gt;</description></item><item><title>Converting a volume name to a device name</title><link>https://remkoweijnen.nl/blog/2008/12/10/converting-a-volume-name-to-a-device-name/</link><pubDate>Wed, 10 Dec 2008 15:41:42 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/12/10/converting-a-volume-name-to-a-device-name/</guid><description>&lt;p&gt;Windows has a couple of different formats for volume names but it is unclear how to convert a Volumename (example: \?\Volume{GUID}) to a DeviceName (example: \Device\HarddiskVolume1).&lt;/p&gt;
&lt;p&gt;I found at that you can use the QueryDosDevice function but you need to remove the preceeding \?\ and the trailing \ of the VolumeName:&lt;/p&gt;</description></item><item><title>Commandline tool to change drive letter assignment</title><link>https://remkoweijnen.nl/blog/2008/12/09/commandline-tool-to-change-drive-letter-assignment/</link><pubDate>Tue, 09 Dec 2008 15:13:27 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/12/09/commandline-tool-to-change-drive-letter-assignment/</guid><description>&lt;p&gt;One of the side effects of using sysprep to prepare an image is that drive letter assignments are reset to default. This behaviour is documented in a &lt;a href="http://support.microsoft.com/kb/928386" target="_blank"&gt;knowledge base article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I previously solved this by running a diskpart script but that needed a custom script for each system (if the disk or partition order differs the script needed to be adjusted). So I needed to run a restore with sysprep determine the drive layout after sysprep, change the script, test by restoring again. So I wrote a commandline tool that can change a drive letter assignment based on the volume label.&lt;/p&gt;</description></item><item><title>Executing a Fast User Switch programmatically - part 2</title><link>https://remkoweijnen.nl/blog/2008/11/26/executing-a-fast-user-switch-programmatically-part-2/</link><pubDate>Wed, 26 Nov 2008 16:45:46 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/11/26/executing-a-fast-user-switch-programmatically-part-2/</guid><description>&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/2008/11/26/executing-a-fast-user-switch-programmatically-part-1/"&gt;Part1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s write our own Credential Server implementation.&lt;/p&gt;
&lt;p&gt;At first, we need to create a named pipe with a unique name. Let&amp;rsquo;s construct the pipe name using a GUID - this should be unique, but we can do it in a cycle to be absolutely sure:&lt;/p&gt;</description></item><item><title>Executing a Fast User Switch programmatically - part 1</title><link>https://remkoweijnen.nl/blog/2008/11/26/executing-a-fast-user-switch-programmatically-part-1/</link><pubDate>Wed, 26 Nov 2008 15:23:37 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/11/26/executing-a-fast-user-switch-programmatically-part-1/</guid><description>&lt;p&gt;I think many of you have got experience with multiple Terminal Server Sessions in windows XP, also called Fast User Switching (FUS). Let&amp;rsquo;s get inside this cool feature.&lt;/p&gt;
&lt;p&gt;How does FUS work? Each session has its own winlogon.exe. It draws the &lt;strong&gt;same&lt;/strong&gt; interface which looks like the screenshot below:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2008/11/default.webp"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align="center"&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2008/12/multiple-users-logged-on-2.webp" class="glightbox" data-type="image" data-gallery="post-149"&gt;&lt;img loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2008/12/multiple-users-logged-on-2-small.webp" alt="multiple-users-logged-on" height="320" width="430" /&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Terminal Server Internals</title><link>https://remkoweijnen.nl/blog/2008/11/19/terminal-server-internals/</link><pubDate>Wed, 19 Nov 2008 17:55:39 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/11/19/terminal-server-internals/</guid><description>&lt;p&gt;Hello, my name is Danila Galimov and i will write here sometimes :-)&lt;/p&gt;
&lt;p&gt;My first post is about communications between Terminal Server sessions and Terminal Server service process (termsrv.exe/dll). Terminal Server service needs to communicate with each session for many tasks, such as sending window message, getting message reply and so on. So, on init, Terminal Server creates a &lt;strong&gt;SmSsWinStationApiPort&lt;/strong&gt; port in global namespace and runs a few WinStationLpcThread threads, which are listening on port and are used to process port messages. When csrss.exe is started, it parses its command line, which usually looks like:&lt;/p&gt;
&lt;blockquote&gt;%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=4096,4096,1024 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=&lt;strong&gt;winsrv&lt;/strong&gt;&lt;em&gt;:UserServerDllInitialization,3 ServerDll&lt;/em&gt;=winsrv:&lt;em&gt;ConServerDllInitialization,2 ProfileControl=Off MaxRequestThreads=16&lt;/em&gt;&lt;/blockquote&gt;
and loads the required dlls (winsrv.dll in our case). Initialization of winsrv.dll creates a thread, which connects to &lt;strong&gt;SmSsWinStationApiPort&lt;/strong&gt; port and does the loop for processing Terminal Server messages until it receives WinStationTerminate message.
&lt;p&gt;We&amp;rsquo;ll try to fool Terminal Server&lt;/p&gt;</description></item><item><title>Working with bitfields in Delphi</title><link>https://remkoweijnen.nl/blog/2008/05/01/working-with-bitfields-in-delphi/</link><pubDate>Thu, 01 May 2008 23:06:00 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/05/01/working-with-bitfields-in-delphi/</guid><description>&lt;p&gt;Recently I needed to convert a C header file to Delphi which contained bitfields. Let&amp;rsquo;s take a look at a sample structure that contains bitfields:&lt;/p&gt;
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;cpp&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".cpp" href="data:text/plain;charset=utf-8;base64,dHlwZWRlZiBzdHJ1Y3QgX0JJVEZJRUxEU1RSVUNUVVJFIHsKICAgIERXT1JEIGR3VmFsdWUxOwogICAgVUxPTkcgQml0VmFsdWUxOiAxOwogICAgVUxPTkcgQml0VmFsdWUyOiAxOwogICAgVUxPTkcgQml0VmFsdWUzOiAxOwogICAgVUxPTkcgQml0VmFsdWU0OiAxOwp9IEJJVEZJRUxEU1RSVUNUVVJFLCAqIEJJVEZJRUxEU1RSVUNUVVJFOw=="&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;_BITFIELDSTRUCTURE&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DWORD&lt;/span&gt; &lt;span class="n"&gt;dwValue1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ULONG&lt;/span&gt; &lt;span class="nl"&gt;BitValue1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ULONG&lt;/span&gt; &lt;span class="nl"&gt;BitValue2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ULONG&lt;/span&gt; &lt;span class="nl"&gt;BitValue3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ULONG&lt;/span&gt; &lt;span class="nl"&gt;BitValue4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;BITFIELDSTRUCTURE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;BITFIELDSTRUCTURE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It means that there is a DWORD (Cardinal) dwValue1 followed by a bitfield with the size of a ULONG (32 bits). In this bitfield 4 values are defined (BitValue1..4) which are used as boolean&amp;rsquo;s because the value can offcourse be 0 or 1. Since Delphi doesn&amp;rsquo;t know a bitfield type the question is how to translate it. Usually it would mean that we simply treat the whole bitfield value as a ULONG and extract the required properties by applying a bitmask (shl/shr). Starting from BDS2006 we can define a record with propertes and use getters and setters. Using this technique we can present boolean values to the user:&lt;/p&gt;</description></item><item><title>How rdp passwords are encrypted 2</title><link>https://remkoweijnen.nl/blog/2008/03/02/how-rdp-passwords-are-encrypted-2/</link><pubDate>Sun, 02 Mar 2008 23:28:57 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/03/02/how-rdp-passwords-are-encrypted-2/</guid><description>&lt;p&gt;Several months ago I &lt;a href="https://remkoweijnen.nl/blog/2007/10/18/how-rdp-passwords-are-encrypted/"&gt;wrote&lt;/a&gt; about encrypting and decrypting RDP passwords. I left one thing open: encrypting the password up to the full 1329 bytes as mstsc does.&lt;/p&gt;
&lt;p&gt;Many people were curious about it so I hope the answer is not a disappointment because it&amp;rsquo;s actually really simple (but I took me a while to figure that out nonetheless). In what I figure is an attempt to hide the password length mstsc always fills up the password with zeroes until it has 512 bytes length.&lt;/p&gt;</description></item><item><title>Vista SP1 changes to Terminal Server API</title><link>https://remkoweijnen.nl/blog/2008/03/02/vista-sp1-changes-to-terminal-server-api/</link><pubDate>Sun, 02 Mar 2008 15:31:55 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/03/02/vista-sp1-changes-to-terminal-server-api/</guid><description>&lt;p&gt;In a previous &lt;a href="https://remkoweijnen.nl/blog/2007/12/19/why-tsadmin-crashes-on-windows-vista/"&gt;article&lt;/a&gt; I wrote about changes in utildll in vista that breaked compatibality for Terminal Server. Even though release notes for Service Pack 1 don&amp;rsquo;t indicate changes or fixes in this area my testing shows that Microsoft has taken over the Windows 2008 implementation of utildll to Vista.&lt;/p&gt;</description></item><item><title>TSAdminEx Progress</title><link>https://remkoweijnen.nl/blog/2008/01/27/test-2/</link><pubDate>Sun, 27 Jan 2008 23:04:07 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/01/27/test-2/</guid><description>&lt;p&gt;I just wanted to show some of the progress that I made in development of TSAdminEx. I thought the best way would be to show some screenshots. Which reminds me I installed a nice Javascript to enlarge the thumbnails, click to see it&amp;hellip;&lt;/p&gt;</description></item><item><title>Using WTSWaitSystemEvent</title><link>https://remkoweijnen.nl/blog/2008/01/25/using-wtswaitsystemevent/</link><pubDate>Fri, 25 Jan 2008 18:02:13 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2008/01/25/using-wtswaitsystemevent/</guid><description>&lt;p&gt;If you develop an application for Terminal Server you might want to react on session events. This means that your application is notified when a user logs on, logs off or becomes idle. This can be done with the &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/aa383856(VS.85).aspx"&gt;WTSWaitSystemEvent&lt;/a&gt; function. Implementing it is rather simple and could look something like this:&lt;/p&gt;</description></item><item><title>Undocumented API's from Utildll</title><link>https://remkoweijnen.nl/blog/2007/12/09/undocumented-apis-from-utildll/</link><pubDate>Sun, 09 Dec 2007 11:05:04 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/12/09/undocumented-apis-from-utildll/</guid><description>&lt;p&gt;Several of Microsoft&amp;rsquo;s Terminal Server tools use undocumented API&amp;rsquo;s from Utildll.dll. For instance Terminal Server Admin uses it to get a localised connect state string and to format time strings like idle time, logon time etc.&lt;/p&gt;
&lt;p&gt;Functions below seems to be the most usefull ones, I will add those to the JwaWinsta unit:&lt;/p&gt;</description></item><item><title>Delphi and Terminal Server Aware</title><link>https://remkoweijnen.nl/blog/2007/11/24/delphi-and-terminal-server-aware/</link><pubDate>Sat, 24 Nov 2007 23:21:37 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/11/24/delphi-and-terminal-server-aware/</guid><description>&lt;p&gt;When an application is not Terminal Server aware (also known as a legacy application), Terminal Server makes certain modifications to the legacy application to make it work properly in a multiuser environment. For example, Terminal Server will create a virtual Windows folder, such that each user gets a Windows folder instead of getting the system&amp;rsquo;s Windows directory. This gives users access to their own INI files. In addition, Terminal Server makes some adjustments to the registry for a legacy application. These modifications slow the loading of the legacy application on Terminal Server and require up to 8 MegaBytes extra memory. This behaviour can be avoided if the TSAware flag is present in the PE header of an executable as can be read &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.vcprojectengine.vclinkertool.terminalserveraware(VS.80).aspx"&gt;here&lt;/a&gt; at MSDN.&lt;/p&gt;</description></item><item><title>More undocumented Terminal Server API's</title><link>https://remkoweijnen.nl/blog/2007/11/09/more-undocumented-terminal-server-apis/</link><pubDate>Fri, 09 Nov 2007 22:42:58 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/11/09/more-undocumented-terminal-server-apis/</guid><description>&lt;p&gt;I added some more undocumented API&amp;rsquo;s to my Jwawinsta unit, the unit is now becoming a collection of the undocumented API&amp;rsquo;s in winsta.dll.&lt;/p&gt;
&lt;p&gt;These are the functions I added:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;WinStationDisconnect&lt;/li&gt;
	&lt;li&gt;WinStationGetProcessSid&lt;/li&gt;
	&lt;li&gt;CachedGetUserFromSid (exported by utildll.dll)&lt;/li&gt;
&lt;/ul&gt;
I also added some more parts of the undocumented structure returned by WinStationQueryInformationW, it now contains:
&lt;ul&gt;
	&lt;li&gt;Session State&lt;/li&gt;
	&lt;li&gt;WinStationName&lt;/li&gt;
	&lt;li&gt;SessionId&lt;/li&gt;
	&lt;li&gt;ConnectTime&lt;/li&gt;
	&lt;li&gt;DisconnectTime&lt;/li&gt;
	&lt;li&gt;LastInputTime&lt;/li&gt;
	&lt;li&gt;LogonTime&lt;/li&gt;
	&lt;li&gt;OutgoingFrames&lt;/li&gt;
	&lt;li&gt;OutgoingBytes&lt;/li&gt;
	&lt;li&gt;OutgoingCompressedBytes&lt;/li&gt;
	&lt;li&gt;IncomingCompressedBytes&lt;/li&gt;
	&lt;li&gt;IncomingFrames&lt;/li&gt;
	&lt;li&gt;IncomingBytes&lt;/li&gt;
	&lt;li&gt;Domain&lt;/li&gt;
	&lt;li&gt;Username&lt;/li&gt;
	&lt;li&gt;CurrentTime&lt;/li&gt;
&lt;/ul&gt;
&lt;section class="comments"&gt;
&lt;h2&gt;2 Comments&lt;/h2&gt;
&lt;ol class="comment-list"&gt;
&lt;li class="comment depth-0"&gt;&lt;div class="comment-meta"&gt;&lt;span class="comment-author"&gt;Chris&lt;/span&gt; &lt;time datetime="2007-12-03"&gt;Dec 3, 2007&lt;/time&gt;&lt;/div&gt;&lt;div class="comment-body"&gt;&lt;p&gt;I would like know how it is possible to access WindowStation and Desktops from a service.&lt;br&gt;
CreateDesktop and similar only works for the current session of the process.&lt;br&gt;
I know there exists NTQueryObject and similar but they are hard to understand and only query kernel objects.&lt;br&gt;
However creating a desktop from a service into another session is a mystery.&lt;/p&gt;</description></item><item><title>How to launch a process in a Terminal Session #2</title><link>https://remkoweijnen.nl/blog/2007/11/08/how-to-launch-a-process-in-a-terminal-session-2/</link><pubDate>Thu, 08 Nov 2007 13:48:18 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/11/08/how-to-launch-a-process-in-a-terminal-session-2/</guid><description>&lt;p&gt;&lt;img width="48" height="48" loading="lazy" decoding="async" align="right" src="https://remkoweijnen.nl/blog/wp-content/uploads/2007/11/cmd.webp" alt="Command Prompt Icon" /&gt;A little while ago I wrote an article on launching a process in another Terminal Session (&lt;a href="https://remkoweijnen.nl/blog/2007/10/20/how-to-launch-a-process-in-a-terminal-session/"&gt;/2007/10/20/how-to-launch-a-process-in-a-terminal-session/&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The article didn&amp;rsquo;t have a demo app yet so I&amp;rsquo;ve attached it here.&lt;/p&gt;</description></item><item><title>JEDI Apilib and JEDI Windows Security Code Library</title><link>https://remkoweijnen.nl/blog/2007/11/08/jedi-apilib-and-jedi-windows-security-code-library/</link><pubDate>Thu, 08 Nov 2007 12:35:32 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/11/08/jedi-apilib-and-jedi-windows-security-code-library/</guid><description>&lt;p&gt;It has been a little silent on the &lt;a target="_blank" href="http://sourceforge.net/projects/jedi-apilib/"&gt;&lt;font color="#22229c"&gt;JEDI Apilib project&lt;/font&gt;&lt;/a&gt; lately, but this will change!&lt;/p&gt;
&lt;p&gt;We had some change in the team members: Marcel van Brakel, founder and large contributor of the project has signed off because he no longer actively uses Delphi. Christian Wimmer has joined the team and he is a very promising member.&lt;/p&gt;
&lt;p&gt;Christian has been working on a new include model (optional) of the Jedi Apilib which has the advantage that you only need to use one unit (JwaWindows) for the whole library.&lt;/p&gt;
&lt;p&gt;Chris has also published the JEDI Windows Security Code Library (Jwscl). This is library that tremendously simplifies using Win32 API calls from Delphi. At this point the library contains:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Windows Version&lt;/li&gt;
	&lt;li&gt;Token&lt;/li&gt;
	&lt;li&gt;Impersonation&lt;/li&gt;
	&lt;li&gt;Login&lt;/li&gt;
	&lt;li&gt;SID&lt;/li&gt;
	&lt;li&gt;Access Control List&lt;/li&gt;
	&lt;li&gt;Security Descriptor&lt;/li&gt;
	&lt;li&gt;Owner, Group, DACL, SACL&lt;/li&gt;
	&lt;li&gt;WindowStation&lt;/li&gt;
	&lt;li&gt;Desktop&lt;/li&gt;
	&lt;li&gt;LSA&lt;/li&gt;
	&lt;li&gt;Rights mapping&lt;/li&gt;
	&lt;li&gt;Secured Objects Files, Registry (+Inheritance), etc.&lt;/li&gt;
	&lt;li&gt;Credentials (Login Dialog)&lt;/li&gt;
	&lt;li&gt;Encryption (MS Crypto API)&lt;/li&gt;
	&lt;li&gt;Well Known SIDs&lt;/li&gt;
	&lt;li&gt;Privileges&lt;/li&gt;
	&lt;li&gt;Security Dialogs (The "ACL Editor" you see on the security yab when you rightclick object in Explorer)&lt;/li&gt;
	&lt;li&gt;Terminal Sessions&lt;/li&gt;
	&lt;li&gt;Unicode + Ansicode&lt;/li&gt;
	&lt;li&gt;Vista Elevation&lt;/li&gt;
	&lt;li&gt;Vista Integrity Level&lt;/li&gt;
&lt;/ul&gt;
Although Jwscl is in beta stage it is already very well useable.</description></item><item><title>Encrypt RDP password in Python</title><link>https://remkoweijnen.nl/blog/2007/11/05/encrypt-rdp-password-in-python/</link><pubDate>Mon, 05 Nov 2007 23:10:29 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/11/05/encrypt-rdp-password-in-python/</guid><description>&lt;p&gt;Dirk Schmitz send me his Python version of encrypting the RDP Password:&lt;/p&gt;
&lt;div class="codecard"&gt;
 &lt;div class="codehead"&gt;
 &lt;span class="codefile"&gt;&lt;/span&gt;
 &lt;span class="codetools" data-pagefind-ignore&gt;
 &lt;span class="codelang"&gt;python&lt;/span&gt;
 &lt;button class="codebtn" type="button" data-copy&gt;Copy&lt;/button&gt;
 &lt;a class="codebtn" download=".py" href="data:text/plain;charset=utf-8;base64,aW1wb3J0IHdpbjMyY3J5cHQKaW1wb3J0IGJpbmFzY2lpCgpwd2RIYXNoID0gd2luMzJjcnlwdC5DcnlwdFByb3RlY3REYXRhKHUiTVlQQVNTV09SRCIsdSdwc3cnLE5vbmUsTm9uZSxOb25lLDApCnByaW50IGJpbmFzY2lpLmhleGxpZnkocHdkSGFzaCk="&gt;Download&lt;/a&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="codebody"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;win32crypt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;binascii&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pwdHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;win32crypt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CryptProtectData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;MYPASSWORD&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;psw&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="n"&gt;binascii&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hexlify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pwdHash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br&gt;Read the original article here: &lt;a href="https://remkoweijnen.nl/blog/2007/10/18/how-rdp-passwords-are-encrypted/"&gt;/2007/10/18/how-rdp-passwords-are-encrypted/&lt;/a&gt;&lt;/p&gt;
&lt;section class="comments"&gt;
&lt;h2&gt;5 Comments&lt;/h2&gt;
&lt;ol class="comment-list"&gt;
&lt;li class="comment depth-0"&gt;&lt;div class="comment-meta"&gt;&lt;span class="comment-author"&gt;Arvid Requate&lt;/span&gt; &lt;time datetime="2010-11-14"&gt;Nov 14, 2010&lt;/time&gt;&lt;/div&gt;&lt;div class="comment-body"&gt;&lt;p&gt;Thank's, this really worked well, after a bit of fiddling (donation will be given asap). For Python 2.7 I had to remove the unicode conversion, otherwise the RDP server would not get the proper password. Interestingly your updated post about 512-byte padding and appending a '0'-character to obtain a 1329 'password 51'-hash did not work for me yet. Did you need the padding as a bugfix or did you suggest it merely as an imrovement to become fully compatible to the MS encoding format? (/2008/03/02/how-rdp-passwords-are-encrypted-2/).&lt;/p&gt;</description></item><item><title>How to get Client IP Address?</title><link>https://remkoweijnen.nl/blog/2007/10/31/how-to-get-client-ip-address/</link><pubDate>Wed, 31 Oct 2007 11:10:10 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/10/31/how-to-get-client-ip-address/</guid><description>&lt;p&gt;When a client is connected to a Terminal Server Session you can use the Terminal Server API to retrieve the client&amp;rsquo;s local IP address.&lt;/p&gt;
&lt;p&gt;Start by enumerating all sessions with &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/aa383833.aspx"&gt;WtsEnumerateSessions&lt;/a&gt; and then for each session get the ClientAddress with a call to &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/aa383838.aspx"&gt;WTSQuerySessionInformation&lt;/a&gt; with the WTSClientAddress parameter. Sound simple, no?&lt;/p&gt;
&lt;p&gt;WTSQuerySessionInformation returns a pointer to a &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/aa383857.aspx"&gt;WTS_CLIENT_ADDRESS&lt;/a&gt; structure. You need to know that the IP address is located at on &lt;em&gt;offset of 2 bytes&lt;/em&gt; in the Address member of WTS_CLIENT_ADDRESS.&lt;/p&gt;
&lt;p&gt;So here&amp;rsquo;s a sample:&lt;/p&gt;</description></item><item><title>New Terminal Server API's in Vista SP1</title><link>https://remkoweijnen.nl/blog/2007/10/30/new-terminal-server-apis-in-vista-sp1/</link><pubDate>Tue, 30 Oct 2007 22:19:25 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/10/30/new-terminal-server-apis-in-vista-sp1/</guid><description>&lt;p&gt;The upcoming Vista SP1 promises 3 new Terminal Server API functions:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb394782.aspx"&gt;WTSConnectSession &lt;/a&gt;: Connects a Terminal Services session to an existing session on the local computer.&lt;/li&gt;
	&lt;li&gt;&lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb394783.aspx"&gt;WTSStartRemoteControlSession&lt;/a&gt;: Starts the remote control of another Terminal Services session.&lt;/li&gt;
	&lt;li&gt;&lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb394784.aspx"&gt;WTSStopRemoteControlSession &lt;/a&gt;: Stops a remote control session.&lt;/li&gt;
&lt;/ul&gt;
If you look in the Windows 2008 beta you can see that the functions are already implemented (in WtsApi32.dll):</description></item><item><title>RDP Clipboard Fix</title><link>https://remkoweijnen.nl/blog/2007/10/25/rdp-clipboard-fix/</link><pubDate>Thu, 25 Oct 2007 17:45:57 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/10/25/rdp-clipboard-fix/</guid><description>&lt;p&gt;Did you ever loose Clipboard functionality (copy/paste) while working with several Terminal Server sessions? I think everyone that works a lot with Terminal Server has experienced this from time to time.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s caused by badly behaving applications. Dimitry Vostokov wrote a tool to fix this issue for Citrix (RepairCBDChain.exe), he explains the issue very well on his blog:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Windows has a mechanism to notify applications about clipboard changes. An application interested in such notifications has to register itself in the so called clipboard chain. Windows inserts it on top of that chain and that application is responsible to propagate changes down the chain:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://citrite.org/blogs/dmitryv/files/2006/12/rc1.JPG"&gt;&lt;em&gt;&lt;img src="http://citrite.org/blogs/dmitryv/files/2006/12/rc1.thumbnail.JPG" alt="rc1.JPG" height="80" /&gt;&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If 3rd-party application forgets to forward notifications down then we have a broken clipboard chain and clipboard changes are not sent via ICA protocol:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Read more at Dimitry&amp;rsquo;s Blog: &lt;a href="http://citrite.org/blogs/dmitryv/2006/12/09/clipboard-issues-explained/"&gt;&lt;a href="http://citrite.org/blogs/dmitryv/2006/12/09/clipboard-issues-explained/"&gt;http://citrite.org/blogs/dmitryv/2006/12/09/clipboard-issues-explained/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So how can we fix this for Terminal Server then?&lt;/p&gt;</description></item><item><title>TSAdminEx</title><link>https://remkoweijnen.nl/blog/2007/10/23/tsadminex/</link><pubDate>Tue, 23 Oct 2007 19:48:50 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/10/23/tsadminex/</guid><description>&lt;p&gt;You will probably know Microsofts Tool to Manage Terminal Server, it&amp;rsquo;s called Terminal Services Manager (you will probably know it as TSAdmin). It can be used to view information about terminal servers including all sessions, users, and processes for each terminal server.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2007/10/tsadmin1.webp" title="TSAdmin Screenshot" class="glightbox" data-type="image" data-gallery="post-32"&gt;&lt;img width="128" height="67" loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2007/10/tsadmin.thumbnail1.webp" alt="TSAdmin Screenshot" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m currently working on a TSAdmin replacement (codename TSAdminEx). Purpose is to show how to use the Terminal Server API&amp;rsquo;s and as a little bonus we will add some extra functionality to TSAdminEx.&lt;/p&gt;</description></item><item><title>How to launch a process in a Terminal Session</title><link>https://remkoweijnen.nl/blog/2007/10/20/how-to-launch-a-process-in-a-terminal-session/</link><pubDate>Sat, 20 Oct 2007 22:45:24 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/10/20/how-to-launch-a-process-in-a-terminal-session/</guid><description>&lt;p&gt;This is an often asked question but the solution is simple:&lt;/p&gt;
&lt;p&gt;So how does it work?&lt;br&gt;
First we obtain the user&amp;rsquo;s primary access token with the &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/aa383840.aspx"&gt;WtsQueryUserToken &lt;/a&gt; API call. To call this function successfully, the calling application must be running within the context of the LocalSystem account and have the SE_TCB_NAME privilege (LocalSystem has this privilege by default). Since the function returns a primary acces token we can just pass this to CreateProcessAsUser and voila!&lt;/p&gt;</description></item><item><title>A referral was returned from the server</title><link>https://remkoweijnen.nl/blog/2007/10/19/a-referral-was-returned-from-the-server/</link><pubDate>Fri, 19 Oct 2007 15:58:48 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/10/19/a-referral-was-returned-from-the-server/</guid><description>&lt;p&gt;Ever tried to run a VBS scripts that queries Active Directory in another domain or from a workstation that is not a domain member? Than you have probably seen this error before:&lt;/p&gt;
&lt;p&gt;&lt;img border="0" width="1" src="wp-content/uploads/2007/10/Referral.png" alt="Error Message" height="1" /&gt;&lt;img border="0" width="1" src="wp-content/uploads/2007/10/Referral.png" alt="Error Message" height="1" /&gt;&lt;img width="318" height="165" loading="lazy" decoding="async" src="https://remkoweijnen.nl/blog/wp-content/uploads/2007/10/referral11.webp" alt="Error Message" /&gt;&lt;/p&gt;
&lt;p&gt;This is because the default settings for Chasing referrals is set to ADS_CHASE_REFERRALS_NEVER.&lt;/p&gt;</description></item><item><title>How rdp passwords are encrypted</title><link>https://remkoweijnen.nl/blog/2007/10/18/how-rdp-passwords-are-encrypted/</link><pubDate>Thu, 18 Oct 2007 21:23:17 +0000</pubDate><guid>https://remkoweijnen.nl/blog/2007/10/18/how-rdp-passwords-are-encrypted/</guid><description>&lt;p&gt;&lt;img width="48" height="48" loading="lazy" decoding="async" align="right" src="https://remkoweijnen.nl/blog/wp-content/uploads/2007/10/mstsc1.webp" alt="mstsc icon" /&gt; Ever wondered how mstsc saves passwords? If you open an RDP file with a text editor like Notepad you can see the encrypted password. In this article I will show you how to encrypt and decrypt these passwords. Besides password recovery this enables you to create rpd files programmatically or perhaps update the password in many rdp files with a batch file.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remkoweijnen.nl/blog/wp-content/uploads/2007/10/rdpscreenshot1.webp" title="RDP Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>