<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JEDI Windows API &#187; JEDI Windows API Headers</title>
	<atom:link href="http://blog.delphi-jedi.net/category/jedi-windows-api-headers/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.delphi-jedi.net</link>
	<description>Joint Endeavor of Delphi Innovators of Windows Programming</description>
	<lastBuildDate>Wed, 19 Oct 2011 18:52:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Slim Read/Write Lock (SRWLock) &#8211; the fast alternative to TMultiReadExclusiveWriteSynchronizer</title>
		<link>http://blog.delphi-jedi.net/2011/09/16/slim-readwrite-lock-the-fast-alternative-to-tmultireadexclusivewritesynchronizer/</link>
		<comments>http://blog.delphi-jedi.net/2011/09/16/slim-readwrite-lock-the-fast-alternative-to-tmultireadexclusivewritesynchronizer/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 08:22:48 +0000</pubDate>
		<dc:creator>chaosben</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=968</guid>
		<description><![CDATA[Another new feature of Windows Vista is the SRW-Lock. It has some advantages compared to a critical section or the TMultiReadExclusiveWriteSynchronizer of Delphi. Lets think about it. The SRWLock was made for the case of a shared resource which will be changed from one ore more threads while there are other threads which want to read [...]]]></description>
			<content:encoded><![CDATA[<p>Another new feature of Windows Vista is the SRW-Lock. It has some advantages compared to a critical section or the <span style="color: #000080">TMultiReadExclusiveWriteSynchronizer</span> of Delphi. Lets think about it.<br />
 <span id="more-968"></span></p>
<p>The SRWLock was made for the case of a shared resource which will be changed from one ore more threads while there are other threads which want to read the resource.<br />
 Of course, this can be done with 1 or 2 critical sections. But 1 critical section will block the writing threads and 2 critical sections are 1 too much.</p>
<p>Optimized for speed and occupying very little memory the SRWLock provides us the basic features of the Delphi-known <span style="color: #000080">TMultiReadExclusiveWriteSynchronizer</span> with an unbelievable performance (in my tests the SRWLock was <strong>at least 10 times faster</strong> then <span style="color: #000080">TMultiReadExclusiveWriteSynchronizer</span>). <br />
 But, as my father likes to say &#8220;Fast and good is never together&#8221;, there are also caveats with the SRWLock: You can&#8217;t elevate a SharedLock to an ExclusiveLock and the lock can&#8217;t be acquired recursively.</p>
<p>Using the SRWLock is quite simple:</p>
<p><strong>1. create a SRWLock </strong></p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> jwaWindows;</p>
<p><span class="kw1">var</span><br />
&nbsp; MyLock : SRWLock;<br />
<span class="kw1">begin</span><br />
&nbsp; InitializeSRWLock<span class="br0">&#40;</span>MyLock<span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>; </div>
<p><strong>2. the reading thread </strong></p>
<div class="dean_ch" style="white-space: wrap;">AcquireSRWLockShared<span class="br0">&#40;</span>MyLock<span class="br0">&#41;</span>;<br />
<span class="co1">//do some reading work</span><br />
ReleaseSRWLockShared<span class="br0">&#40;</span>MyLock<span class="br0">&#41;</span> ;</div>
<p><strong>3. the writing thread </strong></p>
<div class="dean_ch" style="white-space: wrap;">AcquireSRWLockExclusive<span class="br0">&#40;</span>MyLock<span class="br0">&#41;</span>;<br />
<span class="co1">//do some writing work</span><br />
ReleaseSRWLockExclusive<span class="br0">&#40;</span>MyLock<span class="br0">&#41;</span>;</div>
<p>Don&#8217;t try to free the SRWLock &#8230; it&#8217;s done automatically.</p>
<p>The JediAPI-SVN-trunk contains the needed units (jwaWindows or jwaWinBase). Just try it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2011/09/16/slim-readwrite-lock-the-fast-alternative-to-tmultireadexclusivewritesynchronizer/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Condition Variable &#8211; the new way to wait for changes</title>
		<link>http://blog.delphi-jedi.net/2011/09/14/condition-variable-the-new-way-to-wait-for-changes/</link>
		<comments>http://blog.delphi-jedi.net/2011/09/14/condition-variable-the-new-way-to-wait-for-changes/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 10:13:02 +0000</pubDate>
		<dc:creator>chaosben</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=951</guid>
		<description><![CDATA[With Windows Vista we got a new tool for communicating over multiple threads: condition variables. I&#8217;ll try to give you a short overview, tell you, why it is better then events and illustrate the whole theory with some code snippets. Hopefully it will be funny.  :) What is a conditional variable? Condition variables are nothing [...]]]></description>
			<content:encoded><![CDATA[<p>With Windows Vista we got a new tool for communicating over multiple threads: condition variables. I&#8217;ll try to give you a short overview, tell you, why it is better then events and illustrate the whole theory with some code snippets. Hopefully it will be funny.  :)</p>
<p><span id="more-951"></span></p>
<p><strong>What is a conditional variable?</strong></p>
<p>Condition variables are nothing new. They are alread long known in the Unix world, and there are some thread frameworks already offering that feature. But since Windows Vista we have native support for them from the API.</p>
<p>Condition variables are a combination of an event and a corresponding lock. And that&#8217;s where their big advantage lies: With their help you can wait for an event and enter a critical section for example in one atomic operation. This avoids race conditions. At the same time condition variables save resources. In contrast to wait-for procedures they try to avoid trips to kernel mode when possible.</p>
<p><strong>Usage</strong></p>
<p>Usage of condition variables is relatively simple. There are just five functions you have to use. Additionally they follow the new course that they don&#8217;t have to be freed by the application. But foremost they have to be initialized. And that&#8217;s quite straight forward:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">var</span>   <br />
&nbsp; CondVar : TConditionVariable;<br />
<span class="kw1">begin</span><br />
  InitializeConditionVariable<span class="br0">&#40;</span>CondVar<span class="br0">&#41;</span>;<br />
<span class="kw1">end</span></div>
<p>You need not be irritated by the content of the <span style="color: #000080">TConditionVariable</span> record. In most cases the Ptr variable is nil after initialization. It works nonetheless.</p>
<p>A word of caution (born out of painful experience): <span style="color: #000080">TConditionVariable</span> is a record. But it is not the content of the variable that is important but its address in memory. Therefore a simple assignment of CondVar2:=CondVar is no usable condition variable anymore.</p>
<p>Now imagine two threads which work in the same list. One is the producer filling the list. The other one is the consumer taking the items out again.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">var</span><br />
  cvListFilled : TConditionVariable;<br />
  CommonList : TList;<br />
  ListLock : TCriticalSection;</p>
<p><span class="kw1">procedure</span> TProducer.<span class="me1">Execute</span>;<br />
<span class="kw1">begin</span><br />
  <span class="kw1">while</span> <span class="kw1">not</span> Terminated <span class="kw1">do</span><br />
  <span class="kw1">begin</span><br />
    EnterCriticalSection<span class="br0">&#40;</span>ListLock<span class="br0">&#41;</span>;<br />
    <span class="kw1">try</span><br />
      CommonList.<span class="me1">Add</span><span class="br0">&#40;</span>SomeData<span class="br0">&#41;</span>;<br />
    <span class="kw1">finally</span><br />
      LeaveCriticalSection<span class="br0">&#40;</span>ListLock<span class="br0">&#41;</span>;<br />
    <span class="kw1">end</span>;</p>
<p>    WakeConditionVariable<span class="br0">&#40;</span>cvListFilled<span class="br0">&#41;</span>;<br />
    <span class="kw3">Sleep</span><span class="br0">&#40;</span><span class="nu0">500</span><span class="br0">&#41;</span>; <span class="co1">//simulate some work</span><br />
  <span class="kw1">end</span>;<br />
<span class="kw1">end</span>;</p>
<p><span class="kw1">procedure</span> TConsumer.<span class="me1">Execute</span>;<br />
<span class="kw1">begin</span><br />
  <span class="kw1">while</span> <span class="kw1">not</span> Terminated <span class="kw1">do</span><br />
  <span class="kw1">begin</span><br />
    EnterCriticalSection<span class="br0">&#40;</span>ListLock<span class="br0">&#41;</span>;<br />
    <span class="kw1">try</span><br />
      <span class="kw1">while</span> CommonList.<span class="me1">Count</span> = <span class="nu0">0</span> <span class="kw1">do</span><br />
      <span class="kw1">begin</span><br />
        SleepConditionVariableCS<span class="br0">&#40;</span>cvListFilled, ListLock, INFINITE<span class="br0">&#41;</span>;<br />
      <span class="kw1">end</span>;</p>
<p>      CommonList.<span class="me1">Clear</span>;<br />
&nbsp;  &nbsp;<span class="kw1">finally</span><br />
&nbsp;    &nbsp;LeaveCriticalSection<span class="br0">&#40;</span>ListLock<span class="br0">&#41;</span>;<br />
&nbsp;  &nbsp;<span class="kw1">end</span>;</p>
<p>&nbsp;  &nbsp;<span class="kw3">Sleep</span><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span>; <span class="co1">//simulate some work </span><br />
&nbsp; <span class="kw1">end</span>;<br />
<span class="kw1">end</span>;</div>
<p>The TProducer&#8217;s code ist not really surprising. The only really interesting point is <span style="color: #000080">WakeConditionVariable(cvListFilled);</span> which wakes the next thread which listens to <span style="color: #000080">cvListFilled</span>.</p>
<p>TConsumer is much more interesting. After entering the critical section it checks whether there are items that have to be processed at all. If not <span style="color: #000080">SleepConditionVariableCS </span>is called. This call leaves the CriticalSection and puts the thread in sleeping state until the timeout is reached or someone calls a wake procedure. After the sleep call the CriticalSection is entered automatically again. At this point the condition should be checked again since the wake-up call could have caused other threads to do work and change the condition. In our example this could happen if there are more than one consumer and <span style="color: #000080">WakeAllConditionVariable </span>is used.</p>
<p>But what happens when there are more than one TConsumer but you only call <span style="color: #000080">WakeConditionVariable</span>. Each call of <span style="color: #000080">WakeConditionVariable </span>will wake the next thread in line until all TConsumer threads are called. Then a new round starts. As its name says <span style="color: #000080">WakeAllConditionVariable </span>will wake up all threads in line at once.</p>
<p><strong>And now?</strong></p>
<p>All neccessary types and functions are available in the Jedi API svn-trunk. An usage example is <a title="TUO-SVN" href="http://theunknownones.googlecode.com/svn/trunk/Libraries/ThreadHelper/uThreadLists.pas" target="_blank">TWaitList</a>.</p>
<p>Thus it remains only to say: Do it!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2011/09/14/condition-variable-the-new-way-to-wait-for-changes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to Run the OnScreenKeyboard</title>
		<link>http://blog.delphi-jedi.net/2010/11/29/how-to-run-the-onscreenkeyboard/</link>
		<comments>http://blog.delphi-jedi.net/2010/11/29/how-to-run-the-onscreenkeyboard/#comments</comments>
		<pubDate>Mon, 29 Nov 2010 14:30:48 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[DLL]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=899</guid>
		<description><![CDATA[There are lots of questions on the Internt how to run the OnScreen Keyboard on a Windows 64 System from a 32bit Process. Some time ago, I investigated it but due to a lack of time I didn&#8217;t finish it. Today, I want to you show the solution of this problem. From a 32Bit application, [...]]]></description>
			<content:encoded><![CDATA[<p>There are lots of questions on the Internt how to run the OnScreen Keyboard on a Windows 64 System from a 32bit Process. Some time ago, I investigated it but due to a lack of time I didn&#8217;t finish it. Today, I want to you show the solution of this problem.</p>
<p><span id="more-899"></span>From a 32Bit application, Windows makes sure that you cannot access the Windows\System32 folder because this is the place where Windows has all its 64bit DLLs and other files. Since a 32Bit app cannot load 64Bit DLLs, Windows redirects the access to Windows\SysWOW64 folder which is (nearly) a 32Bit copy of the System32 folder. Therefore if you call ShellExecute on the e.g. Windows\System32\osk.exe you actually run Windows\SysWOW64\osk.exe. However the 32Bit version of  OnScreenKeyboard refuses to run on a 64Bit system.</p>
<p>Fortunately, we can disable the redirrection with Wow64DisableWow64FsRedirection.</p>
<p>That leads us to a problem with ShellExecute. It uses internal functions that are located in DLLs. And there is the problem. If a winapi function wasn&#8217;t called before, it will be setup by calling LoadLibrary and GetProcAddress. However, since redirection is offline, LoadLibrary will load a 64Bit DLL which, of course, fails. In such a case ShellExecuteEx returns GetLastError  $7E (127) which defines the error  &#8220;The module specified could not be found &#8220;. I wondered what module was not found and used ProcessExplorer to compare pre- and post situation of ShellExecute. There were many, but only one made ShellExecuteEx work with disabled redirection: MPR.dll (multi protocol router). Step by step disasm returned the that WNetGetConnectionW was loaded from the DLL. So the fix is to load this library before ShellExecuteEx (also ShellExecute) is called.</p>
<pre class="brush:delphi">uses
  JwaWinType,
  JwaWinBase,
  JwaShellAPI,
  JwaSHFolder,
  JwaShlObj;

function Wow64DisableWow64FsRedirection(out OldValue: PVOID): BOOL; stdcall; external 'Kernel32.dll'; //only for JWA &lt; 2.4
function Wow64RevertWow64FsRedirection(const OldValue: PVOID): BOOL; stdcall; external 'Kernel32.dll'; //only for JWA &lt; 2.4

procedure RunOnScreenKeyBoard;
  function GetNativeWindowsDirectory : String;
  var
    P : array[0..MAX_PATH] of Char;
  begin
    SHGetFolderPath(0, CSIDL_SYSTEM, 0, SHGFP_TYPE_DEFAULT, @P);

    result := P;
  end;
var
  oldValue : Pointer;
  Path : String;
  hMpr_DLL : HMODULE;
  ShInfo : SHELLEXECUTEINFO;
begin
  //CoInitializeEx(nil, COINIT_MULTITHREADED or COINIT_DISABLE_OLE1DDE); //*1

  hMpr_DLL := LoadLibrary('mpr.dll'); //*2
  try
    if not Wow64DisableWow64FsRedirection(oldValue) then
      RaiseLastOSError;
    try
      Path := GetNativeWindowsDirectory + '\osk.exe';

      ZeroMemory(@ShInfo, sizeof(ShInfo));
      ShInfo.cbSize := sizeof(ShInfo);
      ShInfo.lpVerb := 'open';
      ShInfo.fMask := SEE_MASK_FLAG_NO_UI or SEE_MASK_NOASYNC;
      ShInfo.lpFile := PChar(Path);

      if not ShellExecuteEx(ShInfo) then
        RaiseLastOSError;
    finally
       Wow64RevertWow64FsRedirection(oldValue);
    end;
  finally
    FreeLibrary(hMpr_DLL);
  end;
end;
</pre>
<p>*1 Has no use here if it was already called. But it is a reminder that it should be called for ShellExecute due to MSDN docs.<br />
 *2 Make sure you don&#8217;t call LoadLibrary when redirection is offline.</p>
<h3>Delphi (addition)</h3>
<p>I forgot to mention that in my experiences, a simple call to ShellExecute works if you run your app in Delphi. You&#8217;ll see that the app already has mpr.dll loaded if you check with Process Explorer. However, running the same app in Windows Explorer it will fail. <br />
 You see that Delphi can have an effect on your application. Therefore, always test your app separately.</p>
<h3>Download</h3>
<p>You can download this file from <a href="https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/trunk/Examples/OSK/64bit OSK/OSK 64 Example.dpr">here</a>.</p>
<h3>Remarks</h3>
<p>I tested this code on my Win7 64bit System only.</p>
<p>The string &#8220;%windir%\sysnative\osk.exe&#8221; was a first guess. However, ShellExecute fails with Error 2 (File Not Found).</p>
<p>Because this is a 64Bit Problem only, I did <strong>not </strong>make extra effort to check for a 64Bit Windows. The function Wow64DisableWow64FsRedirection is not available on a 32Bit platform, so using static linking is a bad idea if you want to use your app on 32Bit.</p>
<p><span style="font-size: large;">If you find this code useful, you may consider a donation? As usual, a donation can be also a WinAPI conversion, examples, bug fixes etc.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/11/29/how-to-run-the-onscreenkeyboard/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Is File In Use</title>
		<link>http://blog.delphi-jedi.net/2010/11/14/is-file-in-use/</link>
		<comments>http://blog.delphi-jedi.net/2010/11/14/is-file-in-use/#comments</comments>
		<pubDate>Sun, 14 Nov 2010 19:57:43 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Conversion]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=861</guid>
		<description><![CDATA[In a thread on DelphiPraxis there was a question that comes up several times a year. However, this time I could remember that there is actually an COM API that can solve the problem. The question was about how to find out which process has a lock on a file. The main problem was, in [...]]]></description>
			<content:encoded><![CDATA[<p>In a thread on DelphiPraxis there was a question that comes up several times a year. However, this time I could remember that there is actually an COM API that can solve the problem. The question was about how to find out which process has a lock on a file. The main problem was, in deed, that I could not remember the API&#8217;s name so Assarbad put some effort in retrieving it. Thanks.<span id="more-861"></span></p>
<p>The name of the API is <a href="http://msdn.microsoft.com/en-us/library/bb775874%28VS.85%29.aspx" target="_blank">IFileIsInUse</a>, an interface. It resides in Shobjidl.h, Shobjidl.idl and newly in JwaShlObj.pas. This is the translation:</p>
<pre class="brush:delphi">{$IFDEF WINVISTA_UP}
const
  IID_IFileIsInUse: TGUID = (
    D1:$64a1cbf0; D2:$3a1a; D3:$4461; D4:($91,$58,$37,$69,$69,$69,$39,$50));

type
  {$ALIGN 4}
  tagFILE_USAGE_TYPE = (
    FUT_PLAYING = 0,
    FUT_EDITING = 1,
    FUT_GENERIC = 2
  );
  FILE_USAGE_TYPE = tagFILE_USAGE_TYPE;
  TFileUsageType = FILE_USAGE_TYPE;

const
  OF_CAP_CANSWITCHTO     = $0001;
  OF_CAP_CANCLOSE        = $0002;

type
  IFileIsInUse = interface(IUnknown)
    ['{64a1cbf0-3a1a-4461-9158-376969693950}']
    function GetAppName(out ppszName: LPWSTR) : HRESULT; stdcall;
    function GetUsage(out pfut : FILE_USAGE_TYPE) : HRESULT; stdcall;
    function GetCapabilities(out pdwCapFlags : DWORD) : HRESULT; stdcall;
    function GetSwitchToHWND(out phwnd : HWND) : HRESULT; stdcall;
    function CloseFile() : HRESULT; stdcall;
  end;

{$ENDIF WINVISTA_UP}
</pre>
<p>The interface can be used as a client and also can be implemented by a server. A client usually checks if a file has a lock and retrieves a pointer to this interface to access the methods. A server usually holds a lock on a given file and implements the interface to provide the methods to the client. This article will discuss only the client side.<br />
 You see that this API only works if both sides do their jobs. A process that locks a file must also implement this interface and register it, so a client can receive a status information. There is no direct link between a file lock and the process name. If a process holds a lock on a file but does not implement the interface you are on your own again. <br />
 Eventually, this is only a shell helper for the nice Windows Explorer deletion dialog.</p>
<p><a href="http://blog.delphi-jedi.net/wp-content/uploads/2010/11/FileInUse-2.png"><img class="alignnone size-full wp-image-869" title="FileInUse Windows Explorer Dialog" src="http://blog.delphi-jedi.net/wp-content/uploads/2010/11/FileInUse-2.png" alt="" width="496" height="293" /></a></p>
<pre class="brush:delphi">  IFileIsInUse = interface(IUnknown)
    function GetAppName(out ppszName: LPWSTR) : HRESULT; stdcall;
    function GetUsage(out pfut : FILE_USAGE_TYPE) : HRESULT; stdcall;
    function GetCapabilities(out pdwCapFlags : DWORD) : HRESULT; stdcall;
    function GetSwitchToHWND(out phwnd : HWND) : HRESULT; stdcall;
    function CloseFile() : HRESULT; stdcall;
  end;
</pre>
<p>The methods of the interface are really easy to understand.</p>
<ul>
<li><em>GetAppName </em>retrieves the name of the process that holds the file. It can be any chosen name by the application designer. To get the name use always a PWideChar and don&#8217;t forget to free it with CoTaskMemFree (it uses the interface IMalloc). Don&#8217;t forget to check for the result. If you like exception you can also rewrite the code using <strong>safecall</strong> (convert the function to a procedure then).</li>
<li><em>GetUsage </em>returns the reason why the file is locked. It can be one of the enumeration constant of  TFileUsage. Either it can be playing a video or music or editing a file. If these are not sufficient the value FUT_GENERIC must be used. Maybe there will be more values in future.</li>
<li> <em>GetCapabilities </em>returns a set of flags in a DWORD. They define whether the file can be closed (OF_CAP_CANCLOSE) by calling <em>CloseFile</em> or the we can put the application into foreground (OF_CAP_CANSWITCHTO). Be aware that you should inform the user that you are about to switch the window. Otherwise she could get nervous about her missing application window. Switching the window can be done by <a href="http://msdn.microsoft.com/en-us/library/ms633539%28VS.85%29.aspx" target="_blank"><em>SetForegroundWindow</em></a>. But your application must have a focus (and some other rules, see MSDN SetForegroundWindow) to switch the window; otherwise nothing happens.</li>
<li><em>GetSwitchToHWND</em> returns a window handle of the other process. Only use this handle to switch to the window. You don&#8217;t really know what window is returned here. Don&#8217;t try to close it or anything else because this is just bad behaviour. At all costs, check the return value. Otherwise you don&#8217;t know whether the returned window handle is valid or just an random number. In worst case it is an existing window from your process. Well, COM rules tell us to nullify the out parameters but usually it is better to check.<br />
 Of course, the call is only valid if GetCapabilities returns the bit OF_CAP_CANSWITCHTO.</li>
<li><em>CloseFile</em> implements the server side of closing the file. The call is only valid if <em>GetCapabilities </em>returns the bit OF_CAP_CANCLOSE. Well, this is really nice. However, don&#8217;t trust it! Always recheck the lock on the file instead of continuing blindly.</li>
</ul>
<p>To retrieve an interface on the file you have to lock it first. Either you download and compile the MSDN example <a href="http://msdn.microsoft.com/en-us/library/ee330722(v=VS.85).aspx" target="_blank">IsFileInUse</a> or you open up an application that implements the interface (e.g. a PDF Reader, MS Office).</p>
<p>The next step is to know where the locked files are placed. The location is the running object table, short ROT (ActiveX.GetRunningObjectTable() retrieves it). It is a global* (on machine) table that holds running COM objects. You can implement your own interfaces and put it in this table. Because interfaces can be arbitrary in its structure and reason to be,  they are attached to monikers (<a href="http://msdn.microsoft.com/en-us/library/ms679705%28VS.85%29.aspx" target="_blank">IMoniker</a>) which describe them uniquely. There are several types of monikers like class, item and file moniker (more information provides IMoniker in MSDN). We are interested in the latter only. <br />
 So the whole work is an enumeration over all monikers in the ROT.  Usually there are not that much in there (I got 5 here). Each moniker is checked for its type (IsSystemMoniker) and if it is a file moniker (MKSYS_FILEMONIKER) the path is compared to the input parameter FileName. Honestly, I cannot tell why there is a comparison of the prefix at first followed by a comparison of the moniker itself, sorry. <br />
 The object itself is retrieved from the moniker by GetObject. It may fail with E_ACCESS_DENIED so a check is done using <em>Succeeded</em>. In the end, we can try to retrieve the IFileIsInUse interface. There may be such a file registered but without the implementation of the interface, thus an additional check.</p>
<p>I didn&#8217;t create this whole source by myself. In fact, there is a <a href="http://msdn.microsoft.com/en-us/library/ee330722(v=VS.85).aspx" target="_blank">FileIsInUse example </a>in MSDN that is the base of this article. The original source is located in the docx file in the download. The example FileIsInUse will create a server.</p>
<p><br class="spacer_" /></p>
<pre class="brush:delphi">function GetFileInUseInfo(const FileName : WideString) : IFileIsInUse;
var
  ROT : IRunningObjectTable;
  mFile, enumIndex, Prefix : IMoniker;
  enumMoniker : IEnumMoniker;
  MonikerType : LongInt;
  unkInt  : IInterface;
begin
  result := nil;

  OleCheck(GetRunningObjectTable(0, ROT));
  OleCheck(CreateFileMoniker(PWideChar(FileName), mFile));

  OleCheck(ROT.EnumRunning(enumMoniker));

  while (enumMoniker.Next(1, enumIndex, nil) = S_OK) do
  begin
    OleCheck(enumIndex.IsSystemMoniker(MonikerType));
    if MonikerType = MKSYS_FILEMONIKER then
    begin
      if Succeeded(mFile.CommonPrefixWith(enumIndex, Prefix)) and
         (mFile.IsEqual(Prefix) = S_OK) then
      begin
       if Succeeded(ROT.GetObject(enumIndex, unkInt)) then
        begin
          if Succeeded(unkInt.QueryInterface(IID_IFileIsInUse, result)) then
          begin
            result := unkInt as IFileIsInUse;
            exit;
          end;
        end;
      end;
    end;
  end;
end;
</pre>
<p><br class="spacer_" /></p>
<h3>Conclusion<br class="spacer_" /></h3>
<p>This whole API has some caveats</p>
<ul>
<li>This API relies on a server that registers an interface in the ROT honestly. If an application doesn&#8217;t do the effort, you will be unable to aquire the name of it.</li>
<li>If you lock a file on a shared folder and you want to access the very same file on the local file system, you cannot determine the process if you access the shared folder from localhost. The reason is Windows itself. Windows is the provider of the file to the outer world (even if it is a loopback) so Windows Explorer shows &#8220;System&#8221; as origin. In the ROT you will see the the UNC path instead of the local file system path. Thus the comparison and our function will fail.</li>
<li>*Security: A ROT is not really global. In fact, there are several ROTs in the system. ROTs are divided by a user and then the mandatory integrity control (MIC) or integrity levels (IL) high, medium and propably low (didn&#8217;t check). If you run as a user, your processes get an medium level and as an Administrator you&#8217;ll get an high integrity level. A server that runs with an medium integrity level will only be allowed to register itself into the medium ROT. So it must be started at least once as Administrator to be allowed to create some Registry keys for COM (LOCAL_MACHINE\Classes\AppID\<em>guid</em>). In this way it will be available in all ROTs if it wants. Unfortunately, this is not the end. On a multi user system, every object in a moniker has a security descriptor that tells COM who is allowed to access it. If Alice wants to access an object in the ROT that was created by Bob, Bob has to explicitily grant Alice access to it. By default the security, which allow access to SYSTEM, Administrators and the creator, is copied from the global COM security settings and can be changed either in the registry for an AppID, at process startup or for each registered object by the server. JWSCL provides all of them in JwsclComSecurity.pas (only Subversion trunk and &gt;= 0.9.4). In this way a server can change the settings to, say, allow all authenticated users access to the object. </li>
</ul>
<h3>Downloads</h3>
<p>You can download the example file from the Subversion directly.</p>
<table border="0">
<tbody>
<tr>
<td><a href="tsvn:https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/trunk/Examples/FileIsInUse/Client/FileIsInUseClientExample.dpr"><img class="size-full wp-image-387 alignnone" title="tortoisecheckout" src="http://blog.delphi-jedi.net/wp-content/uploads/2007/12/tortoisecheckout.png" alt="Checkout with TortoiseSVN" width="48" height="48" /></a></td>
<td><a href="https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/trunk/Examples/FileIsInUse/Client/FileIsInUseClientExample.dpr" target="_blank">https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/trunk/Examples/FileIsInUse/Client/FileIsInUseClientExample.dpr</a></td>
</tr>
</tbody>
</table>
<p><br class="spacer_" /></p>
<h3>Sequel</h3>
<p>The next article discusses the the implementation if the interface IFileIsInUse.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2010/11/14/is-file-in-use/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Windows 7 Taskbar-features via components</title>
		<link>http://blog.delphi-jedi.net/2010/08/18/using-windows-7-taskbar-features-via-components/</link>
		<comments>http://blog.delphi-jedi.net/2010/08/18/using-windows-7-taskbar-features-via-components/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 04:39:49 +0000</pubDate>
		<dc:creator>chaosben</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[Window]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows 7]]></category>

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

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

type
  TOwnerResult = (orNone, orName, orSID);

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

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

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

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

      result := orName;

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

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

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

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

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

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

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

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

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

  OldExitProc := ExitProcessProc;
  ExitProcessProc := MyExitProcessProc;

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

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

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

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=573</guid>
		<description><![CDATA[If you look at the MSDN documentation of CreateProcess you might notice the following remark for the lpCommandLine parameter: The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter [...]]]></description>
			<content:encoded><![CDATA[<p>If you look at the MSDN documentation of <a href="http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx" target="_blank">CreateProcess</a> you might notice the following remark for the lpCommandLine parameter:</p>
<p>The Unicode version of this function, <strong>CreateProcessW</strong>, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a <strong>const</strong> variable or a literal string). If this parameter is a constant string, the function may cause an access violation.</p>
<p>This means that when you move over to Unicode (Delphi 2009/2010) existing code might produce an Access Violation.</p>
<p>This code for example will produce an Access Violation:</p>
<div class="dean_ch" style="white-space: wrap;">CreateProcess<span class="br0">&#40;</span><span class="kw2">nil</span>, <span class="st0">&#8216;notepad.exe&#8217;</span>, <span class="kw2">nil</span>, <span class="kw2">nil</span>, <span class="kw2">False</span>, <span class="nu0">0</span>, <span class="kw2">nil</span>, <span class="kw2">nil</span>, StartupInfo, ProcessInfo<span class="br0">&#41;</span>;</div>
<p>To prevent these kinds of Access Violation we could change the declaration of the lpCommandLine parameter as var. This prevents passing nil though (which is allowed).</p>
<p>So if we want to allow passing nil but not a constant we should declare 2 overloaded functions:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">function</span> CreateProcessW<span class="br0">&#40;</span><br />
&nbsp; lpApplicationName: LPCWSTR;<br />
&nbsp; <span class="kw1">var</span> lpCommandLine: LPWSTR;<br />
&nbsp; lpProcessAttributes, lpThreadAttributes: LPSECURITY_ATTRIBUTES;<br />
&nbsp; bInheritHandles: <span class="kw4">BOOL</span>;<br />
&nbsp; dwCreationFlags: <span class="kw4">DWORD</span>;<br />
&nbsp; lpEnvironment: LPVOID;<br />
&nbsp; lpCurrentDirectory: LPCWSTR;<br />
&nbsp; <span class="kw1">const</span> lpStartupInfo: STARTUPINFOW;<br />
&nbsp; <span class="kw1">var</span> lpProcessInformation: PROCESS_INFORMATION<br />
&nbsp; <span class="br0">&#41;</span>: <span class="kw4">BOOL</span>; <span class="kw1">overload</span>; <span class="kw1">stdcall</span>;<br />
&nbsp;</div>
<p>and</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">function</span> CreateProcessW<span class="br0">&#40;</span><br />
&nbsp; lpApplicationName: LPCWSTR;<br />
&nbsp; lpCommandLine: <span class="kw4">PByte</span>;<br />
&nbsp; lpProcessAttributes, lpThreadAttributes: LPSECURITY_ATTRIBUTES;<br />
&nbsp; bInheritHandles: <span class="kw4">BOOL</span>;<br />
&nbsp; dwCreationFlags: <span class="kw4">DWORD</span>;<br />
&nbsp; lpEnvironment: LPVOID;<br />
&nbsp; lpCurrentDirectory: LPCWSTR;<br />
&nbsp; <span class="kw1">const</span> lpStartupInfo: STARTUPINFOW;<br />
&nbsp; <span class="kw1">var</span> lpProcessInformation: PROCESS_INFORMATION<br />
&nbsp; <span class="br0">&#41;</span>: <span class="kw4">BOOL</span>; <span class="kw1">overload</span>; <span class="kw1">stdcall</span>;<br />
&nbsp;</div>
<p>I choose PByte in the second declaration because it allows for nil but disallows PChar(&#8216;notepad.exe&#8217;) which will also AV.</p>
<p>So what do you think? Should we change this in Jwa?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2009/11/11/createprocess-declaration/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Version Checking for Delphi (2nd Update)</title>
		<link>http://blog.delphi-jedi.net/2009/08/29/version-checking-for-delphi/</link>
		<comments>http://blog.delphi-jedi.net/2009/08/29/version-checking-for-delphi/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 14:07:23 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=392</guid>
		<description><![CDATA[There is an interesting article about checking the version of the operating system. If you are too lazy to read it then just remember this: Do not check it at all! Well, I changed my mind. You should read it! So go to Yochay Kiriaty&#8217;s Article, read it and then get back her for the [...]]]></description>
			<content:encoded><![CDATA[<p>There is an interesting article about checking the version of the operating system. If you are too lazy to read it then just remember this: Do not check it at all!<br />
 Well, I changed my mind. You should read it! So go to <a href="http://windowsteamblog.com/blogs/developers/archive/2009/08/05/version-checking-just-don-t-do-it.aspx" target="_blank">Yochay Kiriaty&#8217;s</a> Article, read it and then get back her for the Delphi part.</p>
<p><span id="more-392"></span>What have we learned from the article?</p>
<ol>
<li>Avoid version checks at all</li>
<li>Check for functionality</li>
<li>Use the right functions</li>
<li>Learn logic</li>
</ol>
<h3>1. It is always frustrating if an application doesn&#8217;t start because of version checking.</h3>
<p>If you have a Win32API function that is not available on older OS, do not use a version check. If you don&#8217;t dive the internal structures of Window it is very likely that your application will work.</p>
<h3>2. Instead: try to load the function with GetProcAddress. If it fails, well then use something else.</h3>
<p>That is the reason why I tell people to set the DYNAMIC_LINK compiler switch when using any of the JEDI functions. In this case the JEDI API libraries loads a function using <em>GetProcedureAddress </em>(located in JwaWinTypes &#8211; don&#8217;t ask me why it is located there).<br />
 GetProcedureAddress can raise two types of Exception.</p>
<ul>
<li>EJwaLoadLibraryError : If a necessary library could not be found.</li>
<li>EJwaGetProcAddressError : If the function could not be located in the library.</li>
</ul>
<p>So now it is easy to write an exception handler:</p>
<pre class="brush:delphi">try
  API_Call(...);
except
  on E1 : EJwaLoadLibraryError do
    //fail safe library not found
  on E2 : EJwaGetProcAddressError do
   //fail safe function not found
end;</pre>
<p>Well, this code only works if you define DYNAMIC_LINK in your project options. Don&#8217;t forget it! If it is not defined, and you try to run your application on an older Windows, it just won&#8217;t start. Instead you get a nasty error message.</p>
<p>Delphi 2010 comes with a new feature that MS Visual C++ people know as <a href="http://msdn.microsoft.com/en-us/library/151kt790.aspx" target="_blank">Linker support for Delay-loaded DLLs</a>.<br />
 Allen Bauer posted an article about this new feature for Delphi under the strange headline <a href="http://blogs.embarcadero.com/abauer/2009/08/25/38894" target="_blank">Procrastinators Unite… Eventually!</a> You can also think of it as &#8220;Delay loaded functions for Delphi&#8221;.</p>
<pre class="brush:delphi">function NewAPIFunction(Parameter : TParameter): BOOL; stdcall;
  external 'user32.dll' name 'NewAPIFunction' delayed;
...

begin
  NewAPIFunction(Parameter);
end;</pre>
<p>Do you recognize the new word &#8220;delayed&#8221; ? If you try to access the function for the first time, it will be loaded automatically from the library &#8220;user32.dll&#8221;. So we don&#8217;t have to be afraid of running the application on an older Windows version. Unfortunately, we also have to add code that checks for the Windows version.</p>
<pre class="brush:delphi">begin
  if OSVersion > 5.1 then
    NewAPIFunction(Parameter);
end;</pre>
<p><span style="font-size: x-small;">(Don&#8217;t be confused about <em>GreaterThan</em>. There is a </span><span style="font-size: x-small;">bug in the code </span><span style="font-size: x-small;">plugin that prevents the greater sign to be shown correctly.)</span></p>
<p>Haven&#8217;t we learned that it is not good to check for the OS version? Shouldn&#8217;t we check for functionality? Apparently, delay loading in Delphi 2010 wasn&#8217;t created with this idea in mind.<br />
 If we change the library name or the function name to something incorrect, like:</p>
<pre class="brush:delphi">function NewAPIFunction(Parameter : TParameter): BOOL; stdcall;
  external 'user32Bla.dll' name 'NewAPIFunction' delayed;
...

begin
  NewAPIFunction(Parameter);
end;</pre>
<p>&#8230;and call this function, at least, I get a nasty <em>EExternalException </em>with the message &#8220;External Exception C0FB007<strong>E</strong>&#8220;.<br />
 Even using the correct library but an incorrect function name doesn&#8217;t change the exception type, but the message :<br />
 &#8220;External Exception C0FB007<strong>F</strong>&#8220;.</p>
<p>Well, It could have been so nice! And in Update 2 we&#8217;re going to see how&#8230;</p>
<pre class="brush:delphi">function NewAPIFunction(Parameter : TParameter): BOOL; stdcall;
  external 'user32.dll' name 'NewAPIFunction' delayed;
...

begin
  try
    NewAPIFunction(Parameter);
  on E1 : ELoadLibraryError do
    //fail safe library not found
  on E2 : EGetProcAddressError do
   //fail safe function not found
end;</pre>
<p>Instead we need to check:</p>
<pre class="brush:delphi">function NewAPIFunction(Parameter : TParameter): BOOL; stdcall;
  external 'user32.dll' name 'NewAPIFunction' delayed;
...

begin
  try
    NewAPIFunction(Parameter);
  on E : EExternalException do
    //failsafe
end;</pre>
<p>However, I wouldn&#8217;t even be sure that this exception type is always the same. <em>EExternalException </em>is always suspect to me, isn&#8217;t it? So in the end it is all about <em>Exception</em>.</p>
<h2>UPDATE</h2>
<p>I was so short sighted! To the COM people  <em>C0FB007E</em> should look quite familiar. Yeah, it is a <a href="http://en.wikipedia.org/wiki/HRESULT" target="_blank">HRESULT</a> code. It maps to</p>
<p>Severity (ERROR_SEVERITY_ERROR = $C) + Facility Code ($FB) + Code (7E and 7F)</p>
<p>Well $7E is 126 in decimal and can be found in JwaWinError.pas as ERROR_MOD_NOT_FOUND. Same goes for $7F =127 which is ERROR_PROC_NOT_FOUND.</p>
<p>Knowing this we can use:</p>
<pre class="brush:delphi">begin
  try
    NewAPIFunction(Parameter);
  on E : EExternalException do
     RaiseLastOSError(Windows.HResultCode(E.ExceptionRecord.ExceptionCode));
  end;
end;</pre>
<p>This exception should be known to Delphi programmers. And you can add another try except block around to catch the Win32 exception.</p>
<p>The exception EExternalException comes from an internal call to <a href="http://msdn.microsoft.com/en-us/library/ms680552%28VS.85%29.aspx" target="_blank">RaiseException</a>.</p>
<h2>UPDATE2:</h2>
<p>If you read the system.pas file from Delphi 2010 you&#8217;ll find the function SetDliFailureHook. It allows us to get notified when an delayed loading error occured.  So how does it look?</p>
<pre class="brush:delphi">uses
  Windows,
  SysUtils;

type
  ELoadLibraryError = class(EWin32Error);
  EGetProcAddressError = class(EWin32Error);

function DelayedFailureHook(dliNotify: dliNotification; pdli: PDelayLoadInfo): Pointer; stdcall;
begin
  case dliNotify of
    dliNoteStartProcessing: ;
    dliNotePreLoadLibrary: ;
    dliNotePreGetProcAddress: ;
    dliFailLoadLibrary   :
      raise ELoadLibraryError.CreateFmt(
        'Failed to load library "%0:s".'#13#10' Error (%1:d) %2:s',[AnsiString(pdli.szDll),
          pdli.dwLastError, SysErrorMessage(pdli.dwLastError)]);
    dliFailGetProcAddress:
      if pdli.dlp.fImportByName then
        raise EGetProcAddressError.CreateFmt(
            'Failed to load function "%0:s" from "%1:s"'#13#10' Error (%2:d) %3:s',[
           AnsiString(pdli.dlp.szProcName), AnsiString(pdli.szDll),
          pdli.dwLastError, SysErrorMessage(pdli.dwLastError)])
      else
        raise EGetProcAddressError.CreateFmt(
            'Failed to load function #%0:d from "%1:s"'#13#10' Error (%2:d) %3:s',[
           pdli.dlp.dwOrdinal, AnsiString(pdli.szDll),
          pdli.dwLastError, SysErrorMessage(pdli.dwLastError)]);

    dliNoteEndProcessing: ;
  end;
end;

...
begin
  SetDliFailureHook(DelayedFailureHook);

  try
    NewAPIFunction(Parameter);
  on E1 : ELoadLibraryError do
    //fail safe library not found
  on E2 : EGetProcAddressError do
   //fail safe function not found
  end;
end.</pre>
<p>All the other errors we don&#8217;t process are converted to an EExternalException error automatically. You can try it out by removing the case dliFailLoadLibrary or dliFailGetProcAddress.</p>
<p>By the way:</p>
<ol>
<li> The function pointer of NewAPIFunction is not nil. It points to an address that does the magic behind the curtain.</li>
<li>If you wonder why the JEDI Windows API hasn&#8217;t implemented this feature: We are still in pre alpha stage.<br />
 You could help by telling us your experience with this feature.</li>
</ol>
<h3>3. Using the right functions can be a bit problematic. There are a lot of possible functions you can use:</h3>
<ol>
<li>JwaWinBase/Windows contains GetVersion and GetVersionEx</li>
<li>There is also a more complex function called VerifyVersionInfo(Ex)</li>
<li>And Delphi comes with a function of its own in SysUtils :  CheckWin32Version</li>
</ol>
<p>CheckWin32Version is little known to Delphi programmers. Instead they create their own complicated classes and tool functions. But if you just want to check for the major and minor version of the OS, try this:</p>
<pre class="brush:delphi">if CheckWin32Version(5, 1) then</pre>
<p>It checks for Windows XP regardless of a service pack. It is the easiest and safest way to check the OS version. But sometimes you need also to know the service pack or even more.</p>
<p>GetVersion and GetVersionEx can be hard to be used. So Microsoft added support for a more flexible and safe way to check the OS version. VerifyVersionInfo was born.</p>
<p>I have translated Yochay Kiriaty&#8217;s example of VerifyVersionInfo for you.</p>
<pre class="brush:delphi">uses
  JwaWinNT,
  JwaNative,
  JwaWinBase;

function IsWindowsXPorLater : Boolean;
const
  Condition = VER_GREATER_EQUAL;
var
  OSInfo : TOSVersionInfoEx;
  ConditionMask : Int64;
begin
  ZeroMemory(@OsInfo, sizeof(OSInfo));
  OSInfo.dwOSVersionInfoSize := SizeOf(OSInfo);
  OSInfo.dwMajorVersion := 5;
  OSInfo.dwMinorVersion := 1;
  OSInfo.wServicePackMajor := 1;
  OSInfo.wServicePackMinor := 0;

  ConditionMask := 0;
  ConditionMask := VerSetConditionMask(ConditionMask, VER_MAJORVERSION, Condition);
  ConditionMask := VerSetConditionMask(ConditionMask, VER_MINORVERSION, Condition);
  ConditionMask := VerSetConditionMask(ConditionMask, VER_SERVICEPACKMAJOR, Condition);
  ConditionMask := VerSetConditionMask(ConditionMask, VER_SERVICEPACKMINOR, Condition);

  result := VerifyVersionInfo(OSInfo, VER_MAJORVERSION or VER_MINORVERSION or
     VER_SERVICEPACKMAJOR or VER_SERVICEPACKMINOR,
     ConditionMask);
end;</pre>
<p>I hope more people are going to use this function.</p>
<h3>4. In the end I also want to write something about logic.</h3>
<p>If you wonder why so many applications ceased to work when Windows Vista came out. Well, if you look at this code you should know why (Windows XP: 5.1 -&gt; Vista: 6.0)</p>
<pre class="brush:delphi"> if (MajorVersion >= 5) and (MinorVersion >= 1) then
 begin 'OK'
 end
 else
 begin
 'Sorry. Old Windows version detected'
 end;</pre>
<p>Well, such a (similar) code is (still) used a lot of times. And it seems to work for Windows 2000 and XP. But in Vista MajorVersion was changed to 6 and, because it was the very first release of version 6, MinorVersion was set to zero. So the if condition stopped working on the second condition check. (BTW: This is a reason why Windows 7 is using version 6.1 instead of version 7.0 .)<br />
 Sometimes we need to apply the <a href="http://en.wikipedia.org/wiki/Mathematical_logic">basic rules of logic</a> (read a good book from <a href="http://www.amazon.co.uk/s/ref=nb_ss?url=search-alias%3Dstripbooks&amp;field-keywords=logic&amp;x=19&amp;y=16">Amazon</a>) or check (nearly) all possible values in a table:</p>
<table style="text-align: center;" border="0">
<thead>
<tr class="wp-caption">
<td>MajorVersion</td>
<td>MinorVersion</td>
<td>Condition Result</td>
</tr>
</thead>
<tbody>
<tr>
<td>&#8230;</td>
<td>&#8230;</td>
<td>&#8230;</td>
</tr>
<tr>
<td>4</td>
<td>1</td>
<td>False</td>
</tr>
<tr>
<td>4</td>
<td>2</td>
<td>False</td>
</tr>
<tr>
<td>4</td>
<td>3</td>
<td>False</td>
</tr>
<tr>
<td>5</td>
<td>0</td>
<td>False</td>
</tr>
<tr>
<td>5</td>
<td>1</td>
<td>True</td>
</tr>
<tr>
<td>5</td>
<td>2</td>
<td>True</td>
</tr>
<tr>
<td>5</td>
<td>3</td>
<td>True</td>
</tr>
<tr>
<td>6</td>
<td>0</td>
<td>False</td>
</tr>
<tr>
<td>6</td>
<td>1</td>
<td>True</td>
</tr>
<tr>
<td>7</td>
<td>0</td>
<td>False</td>
</tr>
<tr>
<td>7</td>
<td>1</td>
<td>True</td>
</tr>
</tbody>
</table>
<p>Not all Windows versions in this table really exists. But how could you know that at that time? So make the table as complete as possible. Then you can change the variables <em>Win32MajorVersion </em>and <em>Win32MinorVersion </em>to the test your if condition and run your application. Software engineers also use unit tests to check the <span style="text-decoration: line-through;">correctness</span> efficiency of their functions.</p>
<p>All in all, if the people of the bad applications had used a function like CheckWin32Version, we hadn&#8217;t this article now:</p>
<pre class="brush:delphi">function CheckWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean;
 begin
 Result := (Win32MajorVersion >AMajor) or
 ((Win32MajorVersion = AMajor) and
 (Win32MinorVersion >= AMinor));
 end;</pre>
<p>But then we couldn&#8217;t blame Microsoft for their bad compatibility. *g*</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2009/08/29/version-checking-for-delphi/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>I&#8217;m burning baby!</title>
		<link>http://blog.delphi-jedi.net/2009/07/18/im-burning-baby/</link>
		<comments>http://blog.delphi-jedi.net/2009/07/18/im-burning-baby/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 05:00:45 +0000</pubDate>
		<dc:creator>chaosben</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[burn]]></category>
		<category><![CDATA[cd]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[disc]]></category>
		<category><![CDATA[IDiscmaster]]></category>
		<category><![CDATA[IMAPI]]></category>
		<category><![CDATA[joliet]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=354</guid>
		<description><![CDATA[You want to burn a CD out of your Delphi application easily? Read on! Based on an article of Bernd Ua and the JWA-translation of the IMAPI Headers, we developed an unit for using the Image Mastering API (IMAPI) in a kind way. You can get it from of the JEDI API Subversion repository or [...]]]></description>
			<content:encoded><![CDATA[<p>You want to burn a CD out of your Delphi application easily? Read on!<span id="more-354"></span></p>
<p>Based on an <a title="article of Bernd Ua" href="http://entwickler.com/itr/online_artikel/psecom,id,631,nodeid,56.html">article of Bernd Ua</a> and the JWA-translation of the IMAPI Headers, we developed an unit for using the <a href="http://msdn.microsoft.com/en-us/library/aa366450%28VS.85%29.aspx">Image Mastering API</a> (IMAPI) in a kind way. You can get it from of the <a href="https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/trunk/Examples/IMAPI">JEDI API Subversion</a> repository or as a zip with binary (<a href="http://blog.delphi-jedi.net/wp-content/uploads/2009/07/imapi.zip">Download</a>). (The in-develop-version can be found in the svn of <a href="http://www.theunknownones.net/" target="_blank">TheUnknownOnes.net</a>)<br />
At the moment it supports only data/Joliet-Discs. But in the next spare time we will also add the audio/Redbook functions.</p>
<h3>How to use it</h3>
<p>After installing the component (TDiscmaster) and dropping it into your application, only a few things are needed to do.<br />
Firstly get the list of available discrecorders.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">var</span><br />
Recorders : TDiscRecorderList;<br />
&#8230;<br />
<span class="kw1">begin</span><br />
&nbsp; Recorders := TDiscRecorderList.<span class="me1">Create</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span>;<br />
&nbsp; DiscMaster1.<span class="me1">GetRecorderList</span><span class="br0">&#40;</span>Recorders<span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</div>
<p>The next step is, to say the discmaster, which recorder should be used. (Be aware: This starts an new image. Every data, added to the previous image, will be deleted).</p>
<div class="dean_ch" style="white-space: wrap;">DiscMaster1.<span class="me1">ActiveRecorder</span> := Recorders<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">DiscRecorder</span>;</div>
<p>The following steps are just fun:</p>
<div class="dean_ch" style="white-space: wrap;">DiscMaster1.<span class="me1">JolietAddFolder</span><span class="br0">&#40;</span><span class="st0">&#8216;c:\My\Folder&#8217;</span>, <span class="st0">&#8216;\folder\on\disc&#8217;</span>, <span class="st0">&#8216;*.*&#8217;</span>, <span class="kw2">true</span>, <span class="kw2">true</span><span class="br0">&#41;</span>;<br />
Discmaster1.<span class="me1">RecordDisc</span><span class="br0">&#40;</span><span class="kw2">false</span>, <span class="kw2">true</span><span class="br0">&#41;</span>;</div>
<p>Thats all. Normally you&#8217;ll get a burned disc now.</p>
<p>Your task for now, is to play around with the control (for example with the Discrecorder.Prop['WriteSpeed']). Take a look at the <a title="MSDN" href="http://msdn.microsoft.com/en-us/library/aa366195%28VS.85%29.aspx">MSDN</a> and get in touch with this way to burn discs. Feel free to ask if something isn&#8217;t clear to you. (I&#8217;ve mentioned only the important things. )</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2009/07/18/im-burning-baby/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

