About Terminal Server, Citrix, Delphi and other stuff
Today I was working on Unattended Installation of an Application called SmartDocuments.
The application seemed to behave nicely on a Multi User (Citrix/Terminal Server) environment: it writes user configuration to the user part of the registry and writes configuration files in a user accessible path.
When testing with a normal user account I ran into a problem though, I got an Oracle ORA-01019 error message:
The English message is ORA01019: unable to allocate memory in the user side.
I suspected this was a permission issue so I ran a trace with Process Monitor but I was unable to find a resolution.
Therefore I assumed this application (or the Oracle client) tried to create an object in the Global namespace because this is a very common issue in Citrix/Terminal Server environments.
See the post Accessing kernel objects in other sessions if you want to learn more about the Object namespace.
My next step was to use the WinObj tool from Sysinternals and I was quickly able to identify the suspect:
I assume the Oracle client is responsible for this and not the actual application but it’s a typical bad design.
Instead of referencing the \Global prefix this application should have used the \Local prefix.
The easiest solution is to give all users the Create Global Objects Privilege but this affects security so I think it’s the least preferred option.
A better solution is to use the Application Compatibilty Toolkit to redirect \Global to \Local using the LocalMappedObject Fix.
If you are not familiar with the Application Compability Toolkit please read my earlier post Using the CorrectFilePaths shim to redirect an ini file to a writable location and Using the CorrectFilePaths Shim with Visual Basic Applications.
So let’s apply the fix!
Open the Compatibilty Administrator (32 bit), create a new database and add a new Fix. Browse to the Program File Location of the Executable that accesses the database (in my case ConnectionManager.exe):
Press Next and press Next again and in the Compatibility Fixes screen select LocalMappedObject and click on the Parameters button:
In the Command line edit enter the parameters:
EDIT: The LocalMappedObject shim simply redirects ALL Global objects to Local (thanks for this info to Chris Jackson) so the Parameter is not needed at all!
Click Finish, save the Database and Install it (read the previous articles for unattended installation of the database).
And not it works nicely:
Note: if the application consists of multiple executables that access the Object you must apply a fix for all of them.
I hope you enjoyed reading this article and found it useful, please leave a comment or rating!
.NET .NET FrameWork Active Directory Altiris Automation Manager bug Citrix datastore Dell Delphi Excel Exchange Exchange2003 Exchange2010 Hack HP iOS Java LinkedIn Linux Lync Office Office 2010 Outlook Passat Password PowerPoint PowerShell RES RNS510 SasLibEx Security Terminal Server ThinApp TSAdminEx Unattended VBS VCDS Vista Visual Basic VMWare Volkswagen Windows PE Wordpress XenApp