Why does my Delphi 5.0 COM+ in process server hang when I use it after I have re-built it with Delphi 2006?

Abstract: Why does my Delphi 5.0 COM+ in process server hang when I use it after I have re-built it with Delphi 2006?

Problem Description

Why does my Delphi 5.0 COM+ in process server hang when I use it after I have re-built it with Delphi 2006?


Problem Resolution

The reason is due to combination of things,

A Change was made to ComServ.pas after Delphi 5.0. The Windows server was set up to sandbox the COM+ server by running the DLL in a particular user context, so that the user only has access to the directory or to the directory and one below that directory.

The problematic code is in the ShortToLongFileName function, here is part of the function:

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
function ShortToLongFileName(FileName: string): string;
var
� FindData: TWin32FindData;� Search: THandle;� 
� PathLength : DWord; //Changed
begin

// Use GetLongPathName where available (Win98 and later) to avoid
� // Win98 SE problems accessing UNC paths on NT/2K/XP based systems

� if Assigned(GetLongPathName) then
��begin
��� SetLength(Result, MAX_PATH + 1);���
PathLength := GetLongPathName(PChar(FileName), @Result[1], MAX_PATH); //Changed���
if PathLength > 0 then
����� SetLength(Result,PathLength); //Changed
� end...

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Now the problem is that GetLongPathName� Windows API, is the cause of the problem, this functions starts from the root directory and traverses down the directories to the target directory, to build up the long path, and of course the user in whose context this code is being executed in COM+ server does NOT have access to these directories,� hence you get a security failure and the function returns a empty string. As this happens in the startup code for the DLL you see the server hanging. The easiest way around this issue is to not use ShortToLongFileName, this function is called by one other function GetModuleFileName.

So all we need to do is modify GetModuleFileName�as follows:

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
function GetModuleFileName: string;
begin�
Result := SysUtils.GetModuleName(HInstance);
end;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>