<?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; DLL</title>
	<atom:link href="http://blog.delphi-jedi.net/tag/dll/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>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>Why aren&#8217;t dialogs themed in elevated COM methods.</title>
		<link>http://blog.delphi-jedi.net/2008/03/14/why-arent-dialogs-themed-in-elevated-com-methods/</link>
		<comments>http://blog.delphi-jedi.net/2008/03/14/why-arent-dialogs-themed-in-elevated-com-methods/#comments</comments>
		<pubDate>Fri, 14 Mar 2008 14:07:33 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[callback]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[dialog]]></category>
		<category><![CDATA[DLL]]></category>
		<category><![CDATA[factory]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[mailinglist]]></category>
		<category><![CDATA[manifest]]></category>
		<category><![CDATA[ProcessExplorer]]></category>
		<category><![CDATA[Theme]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/03/14/why-arent-dialogs-themed-in-elevated-com-methods/</guid>
		<description><![CDATA[I found this question in the borland mailinglist: &#8230; I get my dialog and all runs well &#8211; *except* I&#8217;ve lost theming on this particular dialog. This means the application&#8217;s main windows shows up correctly themed, the progress dialog does not. I&#8217;ve already added the XP manifest to the progress dialog, too, but to no [...]]]></description>
			<content:encoded><![CDATA[<p>I found this question in the <a href="news://newsgroups.borland.com:119/borland.public.delphi.language.delphi.win32">borland mailinglist</a>:</p>
<blockquote><p>&#8230; I get my dialog and all runs well &#8211; *except* I&#8217;ve lost theming<br />
on this particular dialog. This means the application&#8217;s main windows shows<br />
up correctly themed, the progress dialog does not. I&#8217;ve already added the<br />
XP manifest to the progress dialog, too, but to no avail so far.</p></blockquote>
<p>A theme is only applied if an EXE or DLL file has a manifest that explicitly enables theme support. If Windows cannot find this manifest, the process is only shown with the regular window design.</p>
<p><span id="more-47"></span></p>
<p><img src="http://blog.delphi-jedi.net/wp-content/uploads/2008/03/bild-9-1-small.jpg" alt="Bild" height="168" width="225" /><img src="http://blog.delphi-jedi.net/wp-content/uploads/2008/03/bild-12-small.jpg" alt="Bild" height="168" width="225" /></p>
<p>However the Vista elevation is done by creating a COM object and offers its methods through a seperate process. A seperate process is necessary because the same process cannot get assigned the ncessary administrator token. In our case a service in the service container svchost.exe has the task to host the COM object. The contained service is called dllhost.exe (service name: &#8220;COMSysApp&#8221;) and does not run until requested. It does not matter whether the service is deactivated or not because it is started directly by svchost.</p>
<p><a href="http://blog.delphi-jedi.net/wp-content/uploads/2008/03/bild-6.jpg"><img src="http://blog.delphi-jedi.net/wp-content/uploads/2008/03/bild-6-small.jpg" alt="Bild" height="100" width="450" /></a></p>
<p>The COM method and the dialog will run in the process space of the newly elevated dllhost.exe. And because there is no manifest information in this file you cannot get a themed dialog layout.</p>
<p><img src="http://blog.delphi-jedi.net/wp-content/uploads/2008/03/bild-7.jpg" alt="Bild" height="105" width="215" /></p>
<p>So how can you get a themed dialog anyhow?</p>
<p>The task is done by using the basic principles of COM. COM knowns Callback interfaces and other stuff. By using a Callback interface you can turn around the server &#8211; client principle.</p>
<ol>
<li>Define a well known interface that is implemented by the client only. But also known to the server.</li>
<li>Add a parameter to your elevated COM method that receives a pointer to this interface.</li>
<li>Before calling an elevated method, create the interface and</li>
<li>apply a pointer to the method&#8217;s parameter you added.</li>
<li>Call the method and use the methods in the given callback interface. COM will automatically transfer the method calls to your non-elevated process. In this way you can create themed windows, do window management stuff (progress bar) and eventually close the window.</li>
</ol>
<p>If you prefer to read code instead of text you should study this code excerpts.</p>
<p>Define a callback interface for your client and add it to the server&#8217;s TypeLib. Delphi will generate code for it automatically in a file called &lt;Name&gt;_TLB.pas (TLB Header). Do not create the interface by using the Delphi&#8217;s ActiveX expert. Just add it manually.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">type</span><br />
&nbsp; IMyCallback = <span class="kw1">interface</span><span class="br0">&#40;</span><span class="kw4">IUnknown</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#91;</span>MYCALLBACK_GUID<span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="kw1">procedure</span> ACallBackMethod<span class="br0">&#40;</span>DataFromServer : &#8230;<span class="br0">&#41;</span>; <span class="kw1">safecall</span>;<br />
&nbsp; <span class="kw1">end</span>;<br />
&nbsp;<span class="co1">//We do not need a CoClass</span></div>
<p><em>IMyCallback </em>interface is known to both the server and the client, because we use the TLB Header in the client and the server. The client will implement and the server will receive a pointer to it and then call the included method <em>ACallBackMethod</em> everytime it wishes to do so.</p>
<p>The server implements a method to allow a callback interface to be passed to it.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">type</span><br />
&nbsp; IServerInt = <span class="kw1">interface</span><span class="br0">&#40;</span>IDispatch<span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#91;</span>ISERVERINT_GUID<span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="kw1">procedure</span> DoStuffThatNeedsCallBack<span class="br0">&#40;</span><span class="kw1">const</span> Callback: IMyCallback;&#8230;<span class="br0">&#41;</span> <span class="kw1">safecall</span>;<br />
&nbsp; <span class="kw1">end</span>;<br />
&nbsp; <span class="co1">//TypeLib editor also declares a CoClass called CoServerInt</span></div>
<p>Of course you have to implement both interfaces: <em>IServerInt</em> and <em>IMyCallback</em>. However <em>IServerInt </em>is implemented on server side and <em>IMyCallback </em>is only implemented on the client side.</p>
<p>On client side (namely your application) write..</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> &#8230;, ComSrv,ComObj;<br />
<span class="kw1">type</span><br />
&nbsp; TMyCallback = <span class="kw1">class</span><span class="br0">&#40;</span>TComObject, IMyCallback<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">procedure</span> ACallBackMethod<span class="br0">&#40;</span>DataFromServer : &#8230;<span class="br0">&#41;</span>; <span class="kw1">safecall</span>;<br />
&nbsp; <span class="kw1">end</span>;</p>
<p>&#8230;</p></div>
<p>Install the COM object anywhere before you&#8217;re going to use it.</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp;TComObjectFactory.<span class="me1">Create</span><span class="br0">&#40;</span>ComServer,<br />
&nbsp; &nbsp; &nbsp;TMyCallback, Class_MyCallback,<br />
&nbsp; &nbsp; &nbsp;<span class="st0">&#8216;MyCallback&#8217;</span>, <span class="co1">//Classname</span><br />
&nbsp; &nbsp; &nbsp;<span class="st0">&#8216;Description here&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp;ciMultiInstance<span class="br0">&#41;</span>;</div>
<p>After all implement the callback method&#8230;</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">procedure</span> TMyCallback.<span class="me1">ACallBackMethod</span><span class="br0">&#40;</span>DataFromServer : &#8230;<span class="br0">&#41;</span>;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="co1">//do stuff on the non-elevated client side</span><br />
<span class="kw1">end</span>;</div>
<p>&#8230;and anywhere you like, call the method to use our Callback interface.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">var</span> Server : IServerInt;<br />
&nbsp; &nbsp; Callback : IMyCallback;<br />
<span class="kw1">begin</span><br />
&nbsp; Server := CoServerInt.<span class="me1">Create</span>;<br />
&nbsp; Callback := TMyCallback.<span class="me1">Create</span> <span class="kw1">as</span> IMyCallback;</p>
<p>&nbsp; Server.<span class="me1">DoStuffThatNeedsCallBack</span><span class="br0">&#40;</span>Callback, &#8230;<span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</div>
<p>I&#8217;m using TComObject and TComObjectFactory on the client side , because this way works for  console applications, too. If you need the possibilities of TAutoIntfObject, you will have to write a standalone COM server with TApplication. However this is not necessary here.  The method ACallBackMethod will be run in the client&#8217;s process space rather than the elevated helper process. You can check whether the callback method runs in the correct process (elevated or not?) with the following code.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">procedure</span> TMyCallback.<span class="me1">ACallBackMethod</span><span class="br0">&#40;</span>DataFromServer : &#8230;<span class="br0">&#41;</span>;<br />
<span class="kw1">var</span> Token : TJwSecurityToken;<br />
<span class="kw1">begin</span><br />
&nbsp; &nbsp;Token := TJwSecurityToken.<span class="me1">CreateTokenEffective</span><span class="br0">&#40;</span>TOKEN_QUERY <span class="kw1">or</span> TOKEN_READ<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="kw1">try</span><br />
&nbsp; &nbsp; &nbsp;<span class="kw1">if</span> Token.<span class="me1">RunElevation</span> = <span class="nu0">0</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ShowMessage<span class="br0">&#40;</span><span class="st0">&#8216;Process is NOT Elevated: &#8216;</span>+<span class="kw3">IntToStr</span><span class="br0">&#40;</span>GetCurrentProcessId<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp;<span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;ShowMessage<span class="br0">&#40;</span><span class="st0">&#8216;Process is Elevated: &#8216;</span>+<span class="kw3">IntToStr</span><span class="br0">&#40;</span>GetCurrentProcessId<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="kw1">finally</span><br />
&nbsp; &nbsp; &nbsp;Token.<span class="me1">Free</span>;<br />
&nbsp; &nbsp;<span class="kw1">end</span>;<br />
<span class="kw1">end</span>;</div>
<p><u>Second way, still on the client side:</u><br />
If you already have a form class, you can add the interface to it.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">type</span><br />
&nbsp; TForm1 = <span class="kw1">class</span><span class="br0">&#40;</span>TForm, IMyCallback<span class="br0">&#41;</span><br />
&nbsp; <span class="kw1">protected</span><br />
&nbsp; &nbsp; <span class="kw1">procedure</span> ACallBackMethod<span class="br0">&#40;</span>DataFromServer : &#8230;<span class="br0">&#41;</span>; <span class="kw1">safecall</span>;<br />
&nbsp; <span class="kw1">end</span>;</div>
<p>Instead of creating the COM object, you pass a self-pointer to the method parameter.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">procedure</span> TForm1.<span class="me1">OnButtonClick</span><span class="br0">&#40;</span>&#8230;<span class="br0">&#41;</span>;<br />
<span class="kw1">var</span> Server : IServerInt;<br />
&nbsp; &nbsp; Callback : IMyCallback;<br />
<span class="kw1">begin</span><br />
&nbsp; Server := CoServerInt.<span class="me1">Create</span>;</p>
<p>&nbsp; Server.<span class="me1">DoStuffThatNeedsCallBack</span><span class="br0">&#40;</span><span class="kw2">Self</span>, &#8230;<span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</div>
<p>Be aware that in a multi thread environment, you have to make sure that resources in that specific form are accessed only by one thread at a time.</p>
<p>Eventually the server side calls the methods within the callback interface:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> &#8230;, ComSrv,ComObj; </p>
<p><span class="kw1">type</span><br />
&nbsp; TServerIntImpl = <span class="kw1">class</span><span class="br0">&#40;</span>TAutoObject, IServerInt<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">procedure</span> DoStuffThatNeedsCallBack<span class="br0">&#40;</span><span class="kw1">const</span> Callback: IMyCallback;&#8230;<span class="br0">&#41;</span> <span class="kw1">safecall</span>;<br />
&nbsp; <span class="kw1">end</span>;</p>
<p>&#8230;<br />
<span class="kw1">procedure</span> TServerIntImpl.<span class="me1">DoStuffThatNeedsCallBack</span><span class="br0">&#40;</span><span class="kw1">const</span> Callback: IMyCallback;&#8230;<span class="br0">&#41;</span><br />
<span class="kw1">begin</span><br />
&nbsp; &#8230;<br />
&nbsp; <span class="me1">Callback</span>.<span class="me1">ACallBackMethod</span><span class="br0">&#40;</span>&#8230;<span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</p>
<p>&#8230;<br />
<span class="kw1">initialization</span><br />
&nbsp; TAutoObjectFactory.<span class="me1">Create</span><span class="br0">&#40;</span>ComServer, TMyCallback,<br />
&nbsp; &nbsp; &nbsp;Class_MyCallback, ciMultiInstance<span class="br0">&#41;</span>;</div>
<p>The callback method will be called in the context of the client. So it will not be elevated. This is because there is no ordinary method call here. COM will pack the function stack and all its parameter into a stream, send it to the client, unpack it and restore a proper function stack to be executed. This happens in the client process of course.<br />
Get more information about COM callbacks <a href="http://www.informit.com/articles/article.aspx?p=130494&amp;seqNum=5" title="Go to external link.">here</a>.</p>
<hr size="2" width="100%" />Aside from the themed dialog problem you never should show window elements in such an elevated method. There is no need to it. All window elements can be displayed by using standard user rights. They do not need Administrator rights; otherwise we had to logon as Administrator.<br />
However you only should do stuff that needs Administrator privileges in these COM methods. The more code you add to the method the more likely a bug may lead to a security risk. So simply call your function that needs Administrator rights, get the results and go back to Standard user rights. There is really no need to display a window with Administrator privilege.<br />
<hr size="2" width="100%" /><strong>Tell me how you liked this blog entry by adding a comment.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/03/14/why-arent-dialogs-themed-in-elevated-com-methods/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Run a program elevated.</title>
		<link>http://blog.delphi-jedi.net/2008/03/13/run-a-program-elevated/</link>
		<comments>http://blog.delphi-jedi.net/2008/03/13/run-a-program-elevated/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 12:53:21 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[Common]]></category>
		<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[certificate]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[DLL]]></category>
		<category><![CDATA[elevated]]></category>
		<category><![CDATA[elevation]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[RunEl]]></category>
		<category><![CDATA[sign]]></category>
		<category><![CDATA[Vista]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/03/13/run-a-program-elevated/</guid>
		<description><![CDATA[Today I want to introduce a really useful application from the examples in JEDI Windows Security Code Library. In Windows Vista there is no possible way to run a program elevated from the command line. But today there is a cure. I call it RunEl, which stands for Run Elevated. This simple program uses Delphi, [...]]]></description>
			<content:encoded><![CDATA[<p>Today I want to introduce a really useful application from the examples in JEDI Windows Security Code Library. In Windows Vista there is no possible way to run a program elevated from the command line. But today there is a cure. I call it RunEl, which stands for <strong>Run El</strong>evated. This simple program uses Delphi, the JEDI API and JEDI WSCL. It runs only in Windows Vista and Server 2008 with activated UAC. If there is no UAC, it simply starts the requested application.</p>
<p><span id="more-60"></span><br />
If you start the program without any parameter, you&#8217;ll get the help screen.</p>
<blockquote><p>RunEl V1.0 &#8211; Run application elevated<br />
by Christian Wimmer @ 2008<br />
Visit us at http://blog.delphi-jedi.net</p>
<p>RunEl [/INSTALL][/UNINSTALL][/W[D][G]] [AppName] [Parameters]</p>
<p>Parameters:<br />
/INSTALL &#8211; installs the RunElCOM.dll. Needed for parameter /D<br />
RunElCOM.dll must be in the same folder as RunEl.<br />
/UNINSTALL &#8211; uninstalls the RunElCOM.dll.<br />
W &#8211; Wait for called process to be finished.<br />
D &#8211; uses own elevation COM Class. Before using must be setup with /INSTALL .<br />
G &#8211; uses foreground window to display UAC Prompt on.<br />
Parameters W, D and G must be mixed up with only one &#8220;/&#8221;</p></blockquote>
<p>Despite the INSTALL parameter, you do not have to install the program! I implemented two different ways to elevate an application. There is on the one side ShellExecute, which can elevate an application by passing &#8220;runas&#8221; as a parameter. On the other hand, I implemented the usual way by registering a COM DLL. In the last case, you have to register the DLL first. We get back there later.</p>
<p>Let&#8217;s see how we can use it. Open a command line window and type:</p>
<blockquote><p>RunEl cmd</p></blockquote>
<p>This command starts the Windows command line interpreter as an Administrator. You get the UAC prompt, allow the action and a new cmd window is opened. If you disallow the action, RunEl will return an error value through its process return value. This us useful if you want to check the errorlevel in a batch file.</p>
<blockquote><p>Elevation failed. (2147943623) The operation was canceled by the user.</p></blockquote>
<p>If you need to wait for the process to be closed, you can add the <strong>w</strong>ait parameter. This is also mandatory if you want to check your application&#8217;s return value. Because it is clear that we have to wait until the process&#8217; end to get the return value.</p>
<blockquote><p>RunEl /w cmd</p></blockquote>
<p>Sometimes the UAC prompt does not appear and just blinks in the task to get attention. This is because there is no available window. In this case you can specify parameter &#8220;g&#8221;, which uses the foreground window. The UAC prompt will appear again then.</p>
<blockquote><p>RunEl /g cmd</p></blockquote>
<p>Of course you can also combine both parameters. However there must only be one slash.<br />
All these combinations are the same, so it ignores the case-sensitivity and the order of the three options letters.</p>
<blockquote><p>RunEl /wg cmd<br />
RunEl /gw cmd<br />
RunEl /Gw cmd<br />
RunEl /GW cmd</p></blockquote>
<p>The last parameter &#8220;d&#8221; takes the usual way to get elevated privileges. It runs a COM method as the elevated user, creates the process, returns to non-elevated status and then eventually waits for the process or returns immediately.<br />
However you have to install the provided DLL <em>RunElCOM.dll</em> at first. This is done by using RunEl.</p>
<blockquote><p>RunEl /install<br />
The COM DLL was successfully installed.</p></blockquote>
<p>Now you are able to run applications with the &#8220;d&#8221; parameter in the nearly same way as shown above.</p>
<blockquote><p>Run /d cmd<br />
Run /dw cmd<br />
Run /dwg cmd<br />
&#8230;</p></blockquote>
<p>I say nearly because of two issues:</p>
<ol>
<li>You always have to use /d parameter. Otherwise ShellExecute is used</li>
<li>A major problem of ShellExecute is that it ignores the current directory if it is used for elevation. I circumnavigated this problem by using the following command line internally.<br />
<blockquote><p>cmd /C cd /d &lt;current dir&gt; &amp; &lt;your application&gt; &lt;parameters&gt;</p></blockquote>
<p>The disadvantage of this solution is that you do not get the application&#8217;s return value. Cmd is the main process, so we get its return value instead of &lt;your application&gt;.<br />
If you need the correct return value directly, you have to use /d switch.</li>
</ol>
<p>In the end you can uninstall the COM library.</p>
<blockquote><p>runel /uninstall<br />
The COM DLL was successfully uninstalled.</p></blockquote>
<p>If you try to run an application using runel /d you&#8217;ll get the following error message.</p>
<blockquote><p>RunEl /d cmd<br />
Elevation failed. (2148007959) The class is not configured to support Elevated activation.</p></blockquote>
<hr size="2" width="100%" /><u>Statement:</u><br />
I did not sign my application. So you&#8217;ll always get a nasty UAC dialog. But there are several solutions:</p>
<ol>
<li>Do nothing and accept this dialog</li>
<li>Wait until I buy or get the very expensive sign certificate. I tell you that it will last a really long time.</li>
<li>Use your own certificate to sign the file</li>
</ol>
<p><strong><u>Download and Sourecode:</u></strong></p>
<p>You get the newest version of RunEl in the <a href="http://blog.delphi-jedi.net/2008/03/13/download-runel/" title="Go get RunEl.">JWSCL Download section of RunEl</a>.</p>
<p>RunEl is also available through Subversion repository:</p>
<blockquote><p><a href="https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwscl/trunk/examples/runel">https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwscl/trunk/examples/runel</a></p></blockquote>
<p>You can browse the repository or download it with a Subversion client.</p>
<p>Please send bugs to <a href="mailto:mail@delphi-jedi.net">mail@delphi-jedi.net</a> , the <a href="http://sourceforge.net/mail/?group_id=121894" title="Go get more information about our mailinglists.">mailinglist</a> or the <a href="http://sourceforge.net/tracker/?group_id=121894" title="Go to tracker on SF.">forum</a>.</p>
<hr size="2" width="100%" /><strong>Tell me how you liked this blog entry by adding a comment.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/03/13/run-a-program-elevated/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Article about WinAPI programming</title>
		<link>http://blog.delphi-jedi.net/2008/03/11/article-about-winapi-programming/</link>
		<comments>http://blog.delphi-jedi.net/2008/03/11/article-about-winapi-programming/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 12:39:09 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows API Headers]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[callback]]></category>
		<category><![CDATA[DLL]]></category>
		<category><![CDATA[dynamic]]></category>
		<category><![CDATA[hook]]></category>
		<category><![CDATA[JWA]]></category>
		<category><![CDATA[libraries]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/03/11/article-about-winapi-programming/</guid>
		<description><![CDATA[I found this very old but still good article about how to use the Windows API. These are the subjects: Part I: The Primer Windows API calls are just calls to dynamic link libraries Loading a dynamic link library Dynamic loading at runtime Resource only dynamic link libraries Stack usage and dynamic link libraries Callback [...]]]></description>
			<content:encoded><![CDATA[<p>I found this very old but still good <a href="http://dn.codegear.com/article/10322">article</a> about how to use the Windows API.</p>
<p>These are the subjects:</p>
<ol>
<li>Part I: The Primer</li>
<li>Windows API calls are just calls to dynamic link libraries</li>
<li>Loading a dynamic link library</li>
<li>Dynamic loading at runtime</li>
<li>Resource only dynamic link libraries</li>
<li>Stack usage and dynamic link libraries</li>
<li>Callback functions</li>
<li>The Hook functions</li>
<li>Data storage in dynamic link libraries</li>
<li>Instanced addresses and thunking</li>
<li>Part II: Getting our hands dirty</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/03/11/article-about-winapi-programming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

