Category Archives: Coding

Solving Poor RDP performance for Windows 8 clients under Parallels 8 (OSX Mavericks)

If you are somewhat like me, purchasing a new copy of Parallels each year to receive a couple of “bug-fixes” and “performance updates” ranks somewhere between a visit to the dentist and a prostate exam.

Hence you may probably understand my frustration when I faced serious performance issues accessing a brand new copy of Windows 8.1 remotely via RDP. Via RDP, you ask? Yes, it just so happens that I utilise a “high-end” Windows 8.1 workstation to access my MacBook Pro via VNC. The Windows virtual machines on the MacBook are accessed via RDP. There are also two Linux Virtual Machines that I connect to as well, but mostly via SSH. They are not pertinent to this article, and I’m not sure why I bothered mentioning them in the first place!

The image below may explain how I conduct my daily affairs (cough.)

Parallels RDP performance

The Windows 7 VM was not exhibiting any performance issue, so it was definitely not something that was network related. Allocating additional physical resources (RAM, VRAM) to the Windows 8 VM did nothing to improve performance.

A Google search proved useless. Sure, there were numerous posts that encouraged me to mess around with the TCP auto-tuning feature, namely…

netsh interface tcp set global autotuning=disabled

which didn’t work. You can go ahead and execute the command from an elevated command prompt though, to see if it makes a difference on your hardware.

After sprouting a couple of additional grey hairs, I decided that the best bet towards solving this issue was to determine the type of hardware acceleration used within the VM. RDP on Windows 8.x tends to rely extensively on acceleration within the video drivers on the host. Was it possible that the drivers installed by Parallels weren’t good enough?

I shut down the Virtual Machine and looked at the Configuration –

Configure

From within the configuration dialog box, I clicked on the Hardware tab, followed by Video. I soon saw something very interesting. My pre-existing copy of Windows 7 was using DirectX 9 3d Acceleration. However, the new Windows 8.1 Virtual Machine was configured to use DirectX 10 instead! Could this be the holy grail to my RDP woes? I changed the hardware acceleration to DirectX 9 and rebooted the Virtual Machine…

parallels8-settings

And lo and behold… it worked! RDP performance was as smooth as a hot knife through (low cholesterol) butter, and performance matched my Windows 7 RDP session. I have no idea why this made a difference. I can only speculate that Parallel’s DirectX 10 drivers aren’t optimised for RDP. They are instead most likely optimised for gaming on the same physical machine that runs the virtual machine.

Blocking an application for all users on a machine

Requirement
Administrators and Developers may often want to block a single application for all users on a machine. The method listed below is probably one of the simplest (IMHO) available online.

Problem
The standard technique involving the use of adding a key named DisallowRun to HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer does not work. The DisallowRun trick (as most users have discovered) only works for a single user. Others (including myself) have tried prodding around with the .DEFAULT entry to no avail…

Solution
The solution lies within an alternate set of registry keys which are modifiable through the Local Security Policy tool (secpo.msc). I’ve done the dirty work and listed the actual registry modifications below. Simply copy the content between the BEGIN and END markers into a .reg file of your choice and then run it as an Administrator. Alternately, use your favourite programming language to access, create and write the keys below.

— BEGIN —
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\{F0F4E578-34CA-4B81-B36C-6D01C6DCD3B1}Machine\Software\Policies\Microsoft\Windows\Safer\CodeIdentifiers\0]

[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\{F0F4E578-34CA-4B81-B36C-6D01C6DCD3B1}Machine\Software\Policies\Microsoft\Windows\Safer\CodeIdentifiers\0\Paths]

[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\{F0F4E578-34CA-4B81-B36C-6D01C6DCD3B1}Machine\Software\Policies\Microsoft\Windows\Safer\CodeIdentifiers\0\Paths\{a798b6fd-44d7-4246-a5f3-38003abaecce}]
“Description”=””
“SaferFlags”=dword:00000000
“ItemData”=”C:\\Test\\YourApp.exe”
“LastModified”=hex(b):ee,96,5f,c4,37,ac,cb,01
— END —

Notes

  • The actual application that needs to be blocked is within the ItemData key.
  • The identifier a798b6fd-44d7-4246-a5f3-38003abaecce is a GUID. You should generate one yourself though I suspect that you should be able to use the one within this example without too much of a problem.
  • As usual, this solution comes with no warranties! Use it at your own risk!
  • Yes, I know that there are ways to circumvent this! We’re targeting “casual” users! :)

Using a HttpModule to protect your content from 3rd party referrals.

 There are certain cases under which you may wish to “discourage” external sites from linking directly to public content (images, documents …) on your site. You may for example, prefer to have user’s visit your site first before accessing any of your resources.

The sample code attached to this post illustrates how to use a HttpModule to act as a filter which prevents third-party sites from linking to your content. You can use this approach to prevent others from linking to pages, images and other resources.

Revision History
v1.0  – Initial code base (25/5/2010) – Download from here.

Section 1.0 – Configuration

a. Unzip the file and deploy it to a folder of your choice.

b. Register “non-standard” extensions – You will need (under IIS 5.x and 6) to register non-standard file extensions (e.g. .js, .jpg, .gif etc.). This enables requests for these resources to be channelled via the ASP.NET engine.

The image below depicts .jpg files being associated with the ASP.NET ISAPI engine. You should limit the HTTP verbs to a range that is supported by your web-site.

Add_file_extension

The image below shows the application configuration screen that is used to add file mappings under IIS.

Application_configuration

c. Open the web.config file and locate the  xanWebFilter node. Next, add file extensions that you wish to ban. I’ve added asmx files which would cause requests from third party sites to be redirected to yahoo.com. Similarly, I’ve added a jpg key that causes all non-validated requests to be transferred to banned.htm

   1:      <!-- Xanthium web-filter specific values. -->
   2:      <xanWebFilter>
   3:          <add key="asmx" value="http://yahoo.com"></add>
   4:          <add key="jpg" value="http://localhost/banned.htm"></add>
   5:      </xanWebFilter>

d. Ensure that the web.config file refers to the HTTP Module (IIS <= v6 or IIS7 classic mode)

<system.web>
    <httpModules>
        <add type="XanIISUtils.BannedExtensionFilter"
          name="xanthiumContentFilter"/>
    </httpModules>
</system.web>


web.config changes (IIS7 integrated mode)

<system.web>
    <httpModules>
        <add type="XanIISUtils.BannedExtensionFilter"
          name="xanthiumContentFilter"/>
    </httpModules>
</system.web>

e. Compile the code and run it. You will see that requests for asmx and jpg files that do not have HTTP referrers set will result in redirects to yahoo and banned.htm respectively.

Section 2.0 – How it works

The application makes use of the functionality provided by the HttpModule class which allows HTTP events to be subscribed to. This allows a piece of code for example, to be invoked when a request is received for a resource managed by the ASP.NET subsystem.

In a similar fashion, you could subscribe to the  Http_EndRequest event to append data (for example) to a stream returned by the server.

The following code in BannedExtensionFilter illustrates how an event is registered

public override void Init(HttpApplication app)
{
     ...
 
    // Register handlers that are called each time a request is received.
    app.BeginRequest += new EventHandler(this.Application_BeginRequest);
}

Next, when an event is called, the framework automatically invokes Application_BeginRequest() within BannedExtensionFilter. This method is responsible for determining whether a request should proceed unhindered or should be redirected. The following steps briefly describe the steps performed –

1. Determine whether the requested resource is part of a banned extension. In our example, this would be true for asmx and jpg files.

2. If the file is “black-listed”, determine whether the request should be redirected based on the return value of IsValidRequest().

IsValidRequest() performs a simple check to determine whether the HTTP referrer is set to the current application server. If the referrer is something else – the method flags this request for rejection.

protected Boolean IsValidRequest(HttpApplication app)
 {
    Uri fromUrl = app.Request.UrlReferrer;
    if ( null == fromUrl )
    {
         return false;
     }
 
     // Referrer is not empty - check to see whether it happens to
     // be this server's name
     return _serverName.ToLowerInvariant() == fromUrl.Host ? true : false;
}

Section 2.1 – Expandability

The current method of validating the HTTP request header for the referrer leaves a lot to be desired, you can start by using some sort of cookie/session check to make things more robust as well as to cater to those (usually custom coded) HTTP clients that may not set a referrer. You can either completely replace IsValidRequest() or override it in a derived class.

Section 3.0 – Conclusion

The code helps illustrate how HTTP modules could be better alternatives to performing similar tasks within the (beloved?) global.asax file. You should typically use this approach if –

1. You are using IIS7 in integrated pipeline mode and want to marshal ALL application requests through your code. I realise that I have not yet talked about setting up the handler for IIS7 – I’ll update the article at a later stage.

2. You need to keep the code modular and reusable within multiple applications. All you need to do is to compile the files into a library and store it within the GAC.

3. You believe in keeping a clean, non-complicated global.asax file.

Section 4.0 – Disclaimer

This code is released “as-is” without any sort of warranty. Please feel free to use it and modify it in your own projects. The code has been kept as simple as possible so that key concepts can be easily understood by the reader.

Please do feel to drop me an email if you find the code useful or if you have any questions.

Anand Balaji

Wix – How to forcibly overwrite pre-existing files during installation.

 

 

The fly in the ointment

Wix v2 is a pretty nifty tool but since there are a few nasty surprises in store for those who don’t know exactly what it does behind the scenes. More importantly, the Windows Installer tries to perform the intelligent thing of not installing files if the source and destination are exactly the same. This is done by comparing a checksum of the source and destination files. If the checksums match, the file isn’t overwritten at all!

Why would you want to overwrite the same file?

There are a few cases where you might need to do this. For example, if your application relies on the date-time stamps of files for copy-protection or versioning (amongst other things), the checksum comparison will ensure that files having the same checksums are not overwritten. This is not what you might have expected from an installer as one would logically (and sensibly) expect a well behaved installer to blindly overwrite pre-existing files on disc.

It thus becomes impossible for one to overwrite files that are exactly the same even though their timestamps do not match!

Solution

Fortunately enough there is a “directive” which can override this behaviour. Simply add the following line to your .wxs file –

<Property Id=”REINSTALLMODE” Value=”amus”/>

Conclusion

Admit it! Quick fixes aren’t usually as simple as this little tit-bit! I was lucky to come across this solution on the Internet (after a long and arduous journey) and decided to put it on a page exclusively devoted to this topic. Hope that someone finds it helpful! :)

Anand

Wix – My perfectly imperfect msi file

Wix is an extremely powerful tool that should help you create installers for almost every conceivable type of setup scenario. It’s not without its flaws though and some of its quirks can result in you wasting a not so inconsiderable amount of time. I’ve listed a few of the items that frustrated me. The solutions over here should hopefully prove helpful to you.

My perfectly behaved yet perfectly useless SAPI installer

I had taken the responsibility of creating an installer for one of the products designed by my firm. As part of the install process, the installer needed to install version 5.1 of Microsoft’s Speech Engine.

Microsoft had played their part and created a set of nifty merge (basically a bunch of .MSM files – if you didn’t know that, you’ve got a long way to go buddy!) modules. What could be simpler than adding the msm files to your wixproject, referencing them and then compiling your shiny new creation?

Well to cut to the chase, my spanking new MSI was created. It appeared to install fine but it didn’t actually seem to install all of the files.

Before this incident, the general impression that I got was that MSIs were more of a “plug-and-play” solution and that one didn’t have to worry about the fine intricacies of what the MSM was doing. Wix changed all that…

After a day of accomplishing almost nothing, I came to the conclusion that Wix did almost certainly not know what to do with the contents of the MSI file beyond installing them. My hunch turned out to be correct.

It seems that Wix needs to be (ahem) “prodded” to perform additional tasks that are contained within the MSM database. It won’t do them unless your application –

a. Performs the same tasks as part of its installation routine. For example, if your wxs/wxi files add registry entries as part of the install routine, then Wix will ensure that any registry entries required by the MSM are carried out at runtime as well.

b. Explicitly “prods” Wix to perform one or more tasks within the InstallExecuteSequence directive.

Once you’ve understood that, all you need to do is to add the following snippets of code to your wxs file

<InstallExecuteSequence>
     <RemoveFiles />
     <InstallFiles />
     <WriteRegistryValues />
     <CreateFolders/>
     <RegisterTypeLibraries/>  
     <DuplicateFiles/>
     <RegisterClassInfo/>
     <RegisterProgIdInfo/>
     <SelfRegModules/> 
</InstallExecuteSequence>

You might need to add a few additional entries, but I think that the ones given above should suffice. Note that the WIX team does not count this as a bug. They claim that the MSM files have been “improperly” created. Basically it sounds that a lot of inter-office “blame the other party” nonsense, but I don’t have the time nor the mental-bandwidth to care.

PS: Users of Crystal Reports’ MSM modules may face the same problems too. The solution is more or less the same…

– Anand Balaji