Using CreateOleObject('Outlook.Application') causes "Server execution failed" error when run as administrator - delphi

It's a Delphi XE2 app. Pretty simple. Just calls CreateOleObject('Outlook.Application') and assigns the result to a Variant.
If the program is run as administrator it fails with "Server execution failed", but it works fine and I can get the version number back if I run as the logged in user (without elevated permissions).
Why is this? What is it about running as administrator that stops it from creating the object?

This error is due to a mismatch between the security contexts. Outlook is a singleton, so CreateOleObject will connect to the running instance of Outlook if it is available. COM system refuses to marshal calls between processes with different security contexts.
Either make sure Outlook is not running when calling CreateOleObject or make sure both processes run in the same security context.
You can also switch to Extended MAPI (which is a set of dlls loaded in-proc) used directly or through a wrapper (such as Redemption (I am its author) - its RDO family of objects roughly corresponds to the Namespace object in the Outlook Object Model.).

Related

How to make container installation behave like host machine installation

I'm working with the following:
Docker for Windows v20.10.11
Docker running in Windows container mode
mcr.microsoft.com/windows:1903 base image
Proprietary application installed on top of this base image
Each year we create a Docker image with the latest version of our company's software. However this year's version behaves differently. Host machine installation runs fine. Containerized installation fails to run in certain situations. I can start the application as a simple EXE, for example using the Docker run command. The app will start and show up in "tasklist". However I can't start the app via the COM API, which is a critical requirement. The problem appears to be COM related. Normally we can create COM objects for our software just like for any other application. For example, IE returns a COM object just fine:
Creating these objects for our application works outside containers. However inside the container, our latest installation gives this error:
Access permissions appear to be ok. I tried a couple tests to prove this. First I can install other software like MS Word into a container and create COM objects for that:
Second I tried retrieving + modifying the application's DACL in PowerShell.
Changing access masks or trustees can cause an Access Denied error:
This also appears to confirm the access permissions were Ok by default.
Next I made sure COM is aware of the application. This appears to be fine. I get the same result on host machine and container when running this PS script:
gci HKLM:\Software\Classes -ea 0| ? {$.PSChildName -match '^\w+.\w+$' -and
(gp "$($.PSPath)\CLSID" -ea 0)} | ft PSChildName
The application shows up just like any other. The details show up fine when querying by AppID. LocalServer32 points to the correct EXE:
Some other things I tried:
Querying registry keys. There are 7 keys created when installing our software. These appear identical on host machine install and container install.
Even though permissions appear fine, I still tried logging into the container as alternate users. For example "nt authority\system" is another virtual admin user. I also changed the password of the "builtin\administrator" user to enable logging in with that one. Lastly tried creating new users entirely and adding them to the Administrators user group. All these attempts had the same errors as "builtin\containeradministrator" (default user).
A minor check was ensuring CMD.exe / Powershell is running as x64:
Re-registering the DLLs associated with the installation using regsvr32.
Starting from different base images. https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/container-base-images. The full Win Server base image behaves exactly the same way regarding errors. The smaller Win Server Core base image is even more problematic, as I can't even start the app's EXE manually using that base. Lastly I tried other tags of the full Windows base image such as 20H2 and 2004. Same result from those. Multiarch or x64 makes no difference.
Included the "Ogawa hack" which was historically needed to make MS Office apps function correctly with COM: https://stackoverflow.com/a/1680214/7991646. It could be necessary for other COM apps too, but didn't help with my specific installation.
Is there anything else I can do to diagnose or solve this COM issue?
There are several things to consider:
The Considerations for server-side Automation of Office article states the following:
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
If you are building a solution that runs in a server-side context, you should try to use components that have been made safe for unattended execution. Or, you should try to find alternatives that allow at least part of the code to run client-side. If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution.
The When CoCreateInstance returns 0x80080005 (CO_E_SERVER_EXEC_FAILURE) page describes possible reasons.
If many COM+ applications run under different user accounts that are specified in the This User property, the computer cannot allocate memory to create a new desktop heap for the new user. Therefore, the process cannot start. See Error when you start many COM+ applications: Error code 80080005 -- server execution failed for more information.
Finally, you may find a similar thread here helpful, see Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).

Windows service application self-defense in Delphi ( rad studio )

I am building a Windows service app using Delphi , RAD Studio 10
Upon my investigation I came across with a Eset Windows service which wonderfully was protecting itself from being Stopped or terminated.
On stopping the service using (windows service manager) or (end process button)
or (end task button) following error messages occurs :
The operation couldn't be completed.
access denied.
same thing is true with its registry keys . The error message is :
Can not delete info: Error while deleting key
I tested Administrator access and system access. in both cases i was not successful.
I want to build such self-defense mechanism for my own application protecting my service and registry key.
Any idea would be helpful.
Thank you for your time.
update :
I want to know how i can do it in Delphi ... that's why it is tagged Delphi
and If someone wants to stop the service or uninstall it ....
he or she can just use my own applications UI to do it.
edit 2 :
As Remko mentioned I thnk DACL and ACL is better way to handle it , I couldn't find any good reference for it. Is there any good reference for Delphi language?
Protecting from SCM stop is very easy. Assuming you are using TService, you can handle the TService.OnStop event and set its Stopped parameter to False. And assign an error code to the TService.ErrCode or TService.Win32ErrCode property.
Unless you are writing security software, you really should not protect from TaskManager termination. Admins should be allowed to kill misbehaving processes. That being said, you can use SetSecurityInfo() to assign a DACL to your service process that grants/denies access to particular users and/or groups as needed.
You can also use ChangeServiceConfig2() to configure your service's "failure actions" to restart the service if it terminates unexpectedly.
To protect your Registry key, you can use the lpSecurityAttributes parameter of RegCreateKeyEx(), or use the RegSetKeySecurity() function, to assign a SECURITY_DESCRIPTOR to your key that contains a DACL that grants/denies access to particular users and/or groups as needed.

COM-Addin does not load in Outlook 2010x64 (LoadBehavior set to 2). How to debug "runtime error"?

I have an addin that is written in Delphi XE3/XE4, using the Add-in-Express framework (i.e. not .NET, no VSTO). It is running fine in all 32bit-versions of Outlook as well as the 64bit-version of Outlook 2013. However, under the 64bit-version of Outlook 2010 it simply will not load: The COM-Addin manager tells me "Not loaded. A runtime error occurred during the loading of the COM-Add-in." (i.e. the LoadBehavior-value in the registry got set to 2).
Is there any way to find out what that "runtime error" might be?
I have already put OutputDebugStrings all over my code as well as the VCL and ADX code and not a single one of those appears to ever be reached at all before Outlook unloads the DLL again.
When running in the debugger (via PAServer) any breakpoints I set (e.g. on the begin of the DPR-file or in the initialization of the Classes unit) do not even ever get enabled. Seems to me the DLL is never even loaded into the debugger (this does work fine with Outlook 2013x64).
I also already wrote a dummy host EXE that would instantiate my COM server and call the appropriate methods on the IDTExtensibility2-interface to simulate the actual Outlook host but no errors occur in that case either.
Looking at things with Process Monitor, the addin DLL gets loaded briefly but then immediately gets unloaded again and then the LoadBehavior value is reset.
I checked the Application logs and enabled logging in Outlook itself but so far no hints to the nature of the supposed "runtime error".
All latest updates and service packs were applied to all of Delphi, Add-in-Express, Outlook, Windows. The Windows version is 7 Pro. No other addins are installed.
Any more ideas on what to check?
Add an environment variable VSTO_SUPPRESSDISPLAYALERTS value 0 to that PC that is causing the problem.
Then u can reload the addin from outlook >> options >> Addins >> Manage.
So outlook will try reloading this addin and u will get a popup window with details of the prob...

How to stop a Delphi 6 COM server application re-registering with COM at startup

I have a set of legacy Delphi 6 aplications that are out of process COM servers. In attempting to run these programs as a normal domain user on Windows I see them when running up (without any command line arguments or switches) attempting to update chunks of HKEY_CURRENT_CLASSES. this fails due to lac of permission to the HKCR hive. It appears that the act of running a Delphi 6 COM server causes it to attempt to register its embedded COM types with the system registry.
I do not want this behavior normally. We would do this once during install under and adminatrative account to initalise the COM registry, but would not want to do this under normal running conditions of a non adminastrative account. (if you moniroy the system with sys internals process monitor you can see the failed registry key access attempts).
Is there a command line switch I can pass to a Delphi 6 COM server to prevent this automatic COM registrtion logic?
I don't think you're actually seeing what you think you are...
Delphi only tries to install COM servers if they haven't already been installed. I suspect what you're seeing is your application checking to see if it's registered yet or not. The reason you're seeing the failures is because back in Delphi 6 the registry key would have been opened with ALL_ACCESS rights (D6 was prior to XP/Vista/Win7), and I think that's what's causing your failed registry access attempts.
In answer to your question, though: No, there's no command line switch to prevent the automatic registration logic.
It will always try to register the server from TComServer.Initialize unless the startup parameter is /UNREGSERVER which will remove the registry settings. If the startup parameter is /REGSERVER you will get an exception if the registration failed otherwise it will just swallow the exception. Automatic registration of out-proc COM servers has been removed in later version of Delphi. The only option you have to remove this behavior in Delphi 6 is to modify TComServer.Inititalize to only register the server when FStartMode is smRegServer or smUnregServer.

Delphi DataSnap SocketServer "Failed to create key 211"

If I try to terminate the Borland SocketServer application for Delphi 2009 the message above appears.
The application window remains open and I can only terminate the application in the task manager.
Operating system is Windows 2000 Professional SP4
The same error also occurs with the Delphi 2007 version of scktsrvr
scktsrvr attempts to store its settings under HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Socket Server registry key which probably fails under a limited user account. Try running it as administrator, or as a service.
Edit: you can also modify it to use HKEY_CURRENT_USER, for example. It comes with source code.
Run the socketserver as a service, and add the proper permission to the registry key the service user needs to set. Remember that the user you use to run the SocketServer is important. The server acts like a proxy, and in turn call the DCOM server that implements the remote server. Unless changed, the user of the connecting process is used for DCOM security, thereby you have to ensure the right user is used, or you may lead to big vulnerabilities.

Resources