How to tell CreateProcess I do not require user rights elevation - winapi

I am trying to run an executable file which contains "update" in file name, for example "mycoolupdate", without extension.
If it were a normal "mycoolupdate.exe" file, Windows Explorer in Windows 7 would automatically decide based on the file name that it requires user rights elevation.
I thought it is only a shell behaviour and does not affect "CreateProcess" WinAPI function, especially when the file name does not contain .exe extension, but it does not seem to be true. It turns out that the same rules apply to WinAPI.
So GetLastError returns
The requested operation requires elevation
Is there a way to tell CreateProcess that I do not require user rights elevation despite the suspicious file name?

Starting with Windows Vista a correctly written application is required to have an application manifest.
As a developer you are required to supply this.
In this case, your manifest indicates that your application was correctly written for Windows Vista (or newer). Otherwise Windows assumes that your application is not correctly written for Windows Vista.

Related

How to adjust an executable to have it stop emitting "allow this program app to make changes" in windows 10

We have an ancient win32 product that some customers still want to run in Windows 10, but in some cases several of its components (win32 executables) produce said message when run, while installing and after installing :
"Do you want to allow this app/program to make changes in your PC".
Is there any documentation of what Windows checks to emit the message ?
The message you're seeing is the UAC prompt, and it appears because Windows thinks the program wants admin privileges.
Ancient programs don't have manifests. Modern versions of Windows guess at whether really old programs require admin privileges. If the name of the program sounds like it would be an installer (e.g., setupfoo.exe), it will assume the program needs admin.
But many really old programs, even if they're not installers, often want admin privileges because they often try to do things like save files in the program's installation directory or change machine-wide registry values. If Windows detects a program attempting this and failing because it doesn't have admin privs, it might adjust the program's compatibility options so that next time it runs as an administrator. To check this, right-click on the executable file, choose Properties, and select the Compatibility tab. There you'll find a checkbox named "Run this program as an administrator."
To check if your program has a manifest, open the .EXE in Visual Studio (with just the regular open file command), or other resource viewer/editor tool, and look in the resources to see if it has an RT_MANIFEST resource.
If there is no manifest and the program is well-behaved, you can add one that sets the <requestedExecutionLevel> node to asInvoker.
If it has a manifest, look at the <requestedExecutionLevel> node in the XML. If it's there and it says requiresAdministrator, then there's probably nothing you can do. If it already says asInvoker, then something else is going wrong.
To provide or replace the manifest you have two options. You can create an external manifest file and place it in the same folder with the executable (for some versions of Windows, you also have to tell Windows to rely on the external manifest by changing a registry value).
Alternatively, you can use the manifest tool (mt.exe, which comes with Visual Studio) to embed an appropriate manifest in the executable itself (make a backup of the executable first!). In either case, you want to set the <requestedExecutionLevel> node to asInvoker to avoid the UAC prompt.
Note that, if the program really does need admin privileges, then providing a manifest that says it doesn't will cause the program to fail certain operations. The program might crash, or it might appear to work but silently fail to do something important (like saving your work).
Also note that manifests control other important things that you may have to get right, like marking whether the application is DPI-aware or what Windows versions it supports. So, if you try to add a manifest just to add asInvoker, you might also have to add some other important values. MSDN has lots of documentation on manifests and the manifest tool.

Avoid to bring MSI in compatibility mode "Previous version of Windows"

I have an installer package for a 32-bit Application (built with MakeMsi, originally for Windows XP, and simplicisticly maintained since then), that fails registering a COM server on modern (64-bit) Windows systems (7, 8, 10). This is what I see when trying to install my MSI normally:
Application Error
Exception EOleSysError in module xyz at 000F0B01. Error accessing the OLE registry.
If I bring the MSI in compatibility mode Previous version of Windows, the COM server registers successfully. Since "it's working" somehow, I didn't invest much time in exploring the reasons so far. But finally, I'm exhausted to remember our customers (and sometimes also me) again and again of this precondition, so I wish to fix this issue.
The registration (and de-registration) is done via CustomActions, as I see looking into it using Orca:
"[INSTALLDIR.MYAPP]\placeholder.exe" -regserver
"[INSTALLDIR.MYAPP]\placeholder.exe" -unregserver
For each of those entries, Type is 1122 and Source is INSTALLDIR.MYAPP.
I could imagine that the COM server is started with insufficient privileges in the installation procedure, but aren't installers run automatically with administrator rights? I mean, when I (as a standard user) start the installer by double-clicking it, it shows the UAC prompt before the actual installation takes place. Why are the COM servers not run with elevated rights for their registration and de-registration? It's confusing...
How should I change my MSI to make Windows installer process it successfully?
I assume you know that the problem is in the executable that you're running as a custom action, not anything in Windows Installer. That means the issue will be the code in the executable, and it's probably old and incompatible with later OS versions. You'll need to look at the code to see what it's doing that is unsupported.
Many installs don't bother with self-registration. That data is all static data that can be extracted once and included in the MSI file in registry entries and other COM class tables. This means that there is no need to run code at all during the install.
After learning how to register COM servers the right way, I still was interested to understand, why my MSI package worked before. In other words: what is the crucial change after Windows XP? ...I meanwhile also checked that the MSI works when I run it as an administrator...
As I figured out reading the WiX toolset documentation, there is an attribute Impersonate for CustomAction that controls if the CA is executed with elevated privileges:
This attribute specifies whether the Windows Installer, which executes as LocalSystem, should impersonate the user context of the installing user when executing this custom action. Typically the value should be 'yes', except when the custom action needs elevated privileges to apply changes to the machine.
It refers to the msidbCustomActionTypeNoImpersonateflag in the Type field of the CustomAction Table. The value 1122 I observed in my MSI is decompiled into this:
1024 (flag): msidbCustomActionTypeInScript, or, deferred execution, runs in installation script
64 (flag): msidbCustomActionTypeContinue, or, ignore exit code and continue
34: Custom Action Type 34, or, launch executable via commandline
What I used to "fix" the problem the fast way is, enable the msidbCustomActionTypeNoImpersonate flag (2048) in the CA type (in WiX this would be Impersonate="no").
Translated into my MakeMsi script, I had to use the System attribute in the Type of the ExeCa command as to make self registration work as before:
Type="Deferred Sync AnyRc System"
I'm fully aware that this is only a workaround, since running a COM server for (un-)register is dangerous. And so the solution mentioned in the second section of PhilDWs answer should be preferred: manage COM related static information via registry entries in the MSI. But sometimes you need a fast solution, and sometimes there is no other option, see Euro Micellis comment.

How to update a program (exe) from internet using win32

I've written a Win32 program that at regular intervals retrieves content from a dedicated server on the internet.
Sometimes the Win32 program itself needs to be updated. What I do is exit the said program and run a download-program which replaces the main exe I need to uopdate. This works for users running in Administrator mode but not other mode that has sufficent rights for most tasks. The program runs on it own directory which is not under "c:\Windows\program files\".
I've set a manifest file to no avail.
Is there a workable workaround solution for this (any)?
For security reasons you cannot place files in Program Files without admin rights. If you would be able to this you could in theory change Windows files and place malware as well.
Same goes for Linux and OSX systems.
However you could prompt the user for an Administrator password and gain the admin rights in that way.
You need your updater program to have admin rights. You achieve that by adding the requireAdministrator option in the requestedExecutionLevel section of the application manifest. You said that you have tried this to no avail. Well, you must have got something wrong because this is the solution. You just need to persevere until you get the manifest correct.
I presume that when you say that the [program is not under the Program Files directory you refer to the updater. If the program being updated is not under the Program Files directory then there would seem to be no obvious reason that the updater needs admin rights. If that is so then you need to investigate further.

RegSetValueEx requires run as administrator to work?

I have created a small vb6 application which edits the registry in HKLM hive. It makes use of function RegSetValueEx. But when run the exe file in windows 7 and windows 8 pc it does not edit the registry even if run it in administrator user.
In windows XP it works fine.If i run same application as "run as administrator"(by right clicking exe and then run as) in windows 7 and 8 then it works properly.I think the windows 7 and 8 id designed to work like this only. But is there any method i can edit it without running as administrator? Or is there any code in vb6 which does the same.
Here is my small code
Important:
When checking the code create exe and then run the exe and click on button(HKEY_LOCAL_MACHINE\SOFTWARE\Demo registry gets added in wow32 node because vb6 is a 32 bit appliaction).Running the code directly by opening code allows the registry to change.But creating the exe and then running it gives the problem which is the real time scenario in any application.
Microsoft has been warning developers since Windows 2000 that access to the HKLM branch of the registry should not be performed as normal user, as it will sooner or later be restricted to administrators. They also said you should not write to Program Files.
They didn't enforce that rule until Windows Vista, so nobody felt the need to change anything.
Now you have it: don't write to HKLM as normal user - it doesn't work. Don't write your settings to Program Files. It doesn't work.
Application run by the normal user may write their data to user folders and user hives in the registry, nowhere else.
If your application's sole purpose is to write to that value in the HKLM hive then you will need to add a "requiresAdministrator` manifest to the executable, causing Windows to prompt the user for admin access every time it's run.
If this is a small part of a larger project, then you should use COM elevation or just run a small stub executable with the manifest above, allowing windows to only prompt when it's required.
If your application doesn't require admin access at all then you should stop it trying to write to admin restricted locations, and instead use the user's own HKCU hive.

How to get a Standard EXE and WinService EXE to communicate with each other?

We have an application that is part standard EXE and part WinService EXE. The standard EXE is spawned by the Run section of the registry and comes to life at login under the credentials of the user who just logged in. The WinService EXE is set to Auto Run and therefore is always running and is running as LocalSystem (essentially administrator).
We need these two programs to share data by writing information to XML files.
The app works fine when the logged in user has access to the installed folder (C:\Program Files\ourApp). The Standard EXE writes the data and the WinService EXE reads it without issue, all is well.
However, when the logged in user does not have access to write to the installed folder, the data gets caught up in UAC Virtualization and Data Redirection and ends up somewhere else and the WinService does not find nor cannot read it from the installed folder.
To circumvent this, we tried having both the standard EXE and the WinService EXE write to and read from %ProgramData%. This would work fine except that standard users do not have permissions to write to %ProgramData%.
We cannot use %LocalAppData% because for the logged in user that would be C:\Users\LoggedInUser\AppData\Local and for the winservice it would be C:\Users\Administrator\AppData\Local.
Is there any place left in Vista and Win7 with UAC Virtualization enabled that will allow both a Standard EXE running with only user priveleges and a WinService running as LocalSystem to talk to each other. We tried the registry but the problems are even worse. Also last but not least. We need this to work with XP without any differences in code. Meaning XP also has environment variables for %ProgramData%, %LocalAppData% etc, can it work in both.
Two ideas:
Have each app expose a WCF endpoint using the named pipe
transport, and have them talk to each other over a simple interface
of your choosing.
Use Memory Mapped Files to communicate like
you were with disk files.

Resources