I have a C++ program that launches various MS Access databases (.mdb files), some of which have Startup Restrictions applied to them.
Right now, the only way I know to disable those restrictions is to hold down the shift key until the database finishes loading.
I want my program to simulate the same end result of opening the database with those restrictions disabled, but I don't want to have to make the user hold down the shift key, and I don't want to simulate the shift key myself in the program. It's been my experience that you have to hold the shift key down until the database finishes loading, and that doesn't always take the same amount of time (in my environment anyways). So, I don't see that as a very reliable option.
Does anyone know another approach I could take besides simulating the shift key?
I have looked into the AllowBypassKey property in Access, but even if you set that to true, it still requires the user to hold down the shift key in order to disable the startup options.
I currently use ShellExecute() to launch the database, but I'm open to using another method.
Note: The solution needs to work in Access 2000, 2003, 2007, and 2010
Related
I have been dabbling with working nicely with UAC for a while and I found about a few things:
With UAC enabled, a program in the Startup folder, that requires to be run as admin (say by an embedded manifest), cannot be run according to this Stack Overflow thread.
Another method of running a program at startup is by creating a key containing the path to that application in: HKLM or HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run or HKLM or HKCU\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run in 64 bit machines.
Yet another method is using the task scheduler setting the Run with highest privileges option. This is the only method that bypasses the problem stated in point 1.
Coming from a Linux background, I had no clue about all these admin rights related problems. If someone can list out scenarios which absolutely need administrator privileges, it would be of great help!
I'm asking this because when I'm developing some application, I keep encountering several problems during implementation mostly because my application required admin rights when it shouldn't.
If I know, at design time, all possible scenarios that require admin rights, I could possibly design a common service for all my applications that takes care of all the administrator tasks (I think services are the Windows way of doing things like this).
There really isn't a list of scenarios or API function calls that require elevation. Your best option will probably be to focus on what API calls require elevation. The reason for this is that it may be required only if certain values are passed to the function. For instance CreateFile can create a file in your home directory without elevation but requires it for creating a file in C:\Windows. If the directory is provided through user input the only way you can know if elevation is required is to check the error code when the call fails. If elevation is required the function will set the error status to ERROR_ACCESS_DENIED and return a value indicating failure.
A windows service creates a registry value (for an Excel add-in) under HKEY_CURRENT_USER registry key for each logged on user (by calling ImpersonateLoggedOnUser() and RegSetValueEx()).
I need to delete this registry value when a user logs off, including system shutdown.
If it is not deleted at log off, and the software is uninstalled by one user then the entry in the registry remains for any other user that logged on during the lifetime of the service which causes a message box error to be displayed each time Excel begins because it is attempting to load an add-in that no longer exists.
Considered but rejected the following:
SetConsoleCtrlHandler() because there is no indication of what user is logging off.
REG_OPTION_VOLATILE because it is effective only when creating keys and I am only creating a value (did not thoroughly investigate so may not have been solution even if I was creating a key).
Are there any other mechanisms that would provide a solution to this? Windows versions are XP, Vista and 7.
Since you are already on a service, your life (should be) is easy.
In fact you can register yourself to receive the SERVICE_CONTROL_SESSIONCHANGE event. In particular, you will want to look for the WTS_SESSION_LOGOFF reason.
You have to register for these events in your service control routine, at startup, adding SERVICE_ACCEPT_SESSIONCHANGE. When the event is SERVICE_CONTROL_SESSIONCHANGE, the lpEventData parameter is a pointer to a WTSSESSION_NOTIFICATION structure, with information about the session currently terminating (thus, about the user logging off).
Check out the details on MSDN1, MSDN2, MSDN3 - the data structure that contains the dwSessionId of the interesting session
Check out this related (but not duplicate) question too
That said, I find João Augusto solution cleaner; I would use that for a similar problem; however, I wanted to add this solution for having an answer to the wider question (for future reference readers)
EDIT: Another method is to use SENS, check this MSDN article
An easier approach would be to put a command removing the value in question into the user's RunOnce key, e.g.,
reg.exe delete HKCU\Software\xyzzy /v myvalue /f
so that the unwanted value will be removed when the user next logs in. Note, however, that this might interfere with the creation of the value depending on how you are handling that.
Lets take an example here which is known everywhere in the IT world:
We have a game, for example solitaire, and someone makes and releases a trainer for it that your moves are always '0'.
How do I programatically determine which adresses and what values that "hack" changes?
What way would be the best, if this is possible?
From within the game [injecting/loading my own dll?]
By intercepting traffic between the hack and target process with my own process?
I ask this question because of 2 things:
Protect an application from being "hacked" (at least by the script kiddies)
Reverse engineer a trainer (so you don't have to reinvent the wheel / avoid NIH syndrome)
You can't. Some broken attempts may be setting two addresses and then comparing them (they will find the other address though). Or they can simply remove your compare call.
They can alter any protection function that you use to "programatically determine" to always return false results. They can do anything to your executable, so there is no way.
Unless you hook the kernel functions that open your process to modify the memory. But that is also breakable and if I am not wrong you need to get your "protection kernel driver" digitally signed now.
There is another way in which you load a DLL in every running and newly spawned processes (which will probably alert antiviruses about your program being a virus), with that DLL you hook OpenProcess (and if there is another alternative to it, that too) functions in each process and check if its targeted at your program, and prevent it if so. Search about function hooking. I believe there was something called "MS Detour" or something for it.
And still, the game will not even be close to safe.
To sum up, no way is good to protect your game locally. If you are storing scores or something you should create a server program and client should report every move to server.
Even then, they can create a bot to automatically respond to server. Then the best you can do is somehow verify it is a human that is playing. (maybe captcha or comparing the solving speed with human avarage?)
I'm trying to simulate the keypress events for Win+X on Windows 8 which should pop up a small menu, but I have been unable to get this to work by using SendInput. For any other combination of keys (e.g. Win+R, Win+E, Win+D) it works but not for Win+X. I've noticed that Synergy+ has the same problem, but the Windows on-screen keyboard doesn't. I have also looked at the parameters for SendInput that the on-screen keyboard uses but if I use exactly the same parameters in my application I still don't get the menu.
So my question, how do I get this to work? Or is there an alternative way to display this menu?
I've recently added support for this to our application. Glad we beat our competitor to it!
There are new UIPI restrictions in Windows 8. The most-used blocked shortcut is Alt+Tab, so you're going to want to do the workaround.
You have to mark your binaries with uiAccess="true" in the manifest. (For more detail on how to do this, google.) This manifest prevents binaries from being launched unless signed with a Microsoft-approved code signing certificate and installed in a "secure location" (system32 or Program Files/Program Files (x86)).
If you lanch your program from any helpers: The uiAccess binary can't be launched with CreateProcess from a medium integrity process (the manifest marks it as requiring "high" integrity). Instead, it's easiest to launch it using ShellExecute "open" to get the shell to elevate it. If using CreateProcessAsUser, you have to set TokenUIAccess to 1 using SetTokenInformation, or launching will fail.
Final provisos: note that uiAccess quite heavily restricts what a process can do. You can't receive UI input from normal (medium integrity) processes, so other applications can't interact with your windows. If you don't already follow good practices in separating your UI into a separate process, this would therefore be a good reason to do that. Alternatively, the tasks requiring uiAccess could be put into a small, self-contained helper binary and entirely separated from the non-UI process too. Your main app can run it as a high-integrity helper process that is sent instructions as required to perform those specific tasks (such as SendInput).
Finally, SendInput will work.
Ok, so we have a C++ app that runs fine in Windows XP.
It has the following code in the initialization
// Register all OLE server (factories) as running. This enables the
// OLE libraries to create objects from other applications.
COleObjectFactory::RegisterAll();
Now like i said, it works fine in Windows XP, but as far I understand the program tries to register its COM interface Which is fine in XP, but this may be a problem in Windows Vista and Windows 7 because of the UAC. Especially if its is run as a standard user (with no elevated privileges).
If i understand it correctly this is needed for the program to run properly, but it cant execute this code without elevated privileges. If it will run every time the app runs (this usually runs when CWinApp::init() is run)
Before you say just use admin privileges, the user will not have them, there is no way to change that
So, now my questions are:
1) am i correct in my assumptions?
2) if I am correct, what is the best way around this? Can i just remove this? Do i need to set up some other thing? (we changed some VB modules to use a XML file instead of stuff in the registry
PS: the modules compiles into DLLs
PPS: UAC MUST be on
Take note that:
The documentation for these functions makes no mention of any privilege requirements; and
nobody online seems to be having trouble with these functions in limited privilege environments; and
it's 2012, I think someone would have noticed if these functions didn't work under UAC by now.
So (with nothing to suggest otherwise) I'd say It Just Works.
Notwithstanding the above, I looked at the implementation of COleObjectFactory::RegisterAll() and COleObjectFactory::UpdateRegistryAll().
RegisterAll
Ultimately calling RegisterAll ends up in olefact.cpp:135 where CoRegisterClassObject is called. From MSDN:
Registers an EXE class object with OLE so other applications can connect to it.
I believe this registration will be limited to the current user's session and the lifetime of the application. The Remarks section touches on privileges (As of Windows Server 2003...) but doesn't provide anything concrete.
There's an object known as the Running Object Table (ROT) that can be retrieved via GetRunningObjectTable. The documentation has this snippet:
Each workstation has a local ROT that maintains a table of the objects that have been registered as running on that computer.
The COM Elevation Moniker has some more information about the ROT and privileges (it suggests processes of various privilege levels work fine with it). The links on the left-hand side might help, too.
Overall it seems there's nothing to suggest that CoRegisterClassObject requires administrator permissions.
UpdateRegistryAll
This function ends up in olefact.cpp:375 where it opens HKEY_CLASSES_ROOT. At this point the documentation gets a bit better:
Registry functions such as RegOpenKeyEx or RegQueryValueEx allow you to specify the HKEY_CLASSES_ROOT key. When you call these functions from a process running in the interactive user account, the system merges the default settings in HKEY_LOCAL_MACHINE\Software\Classes with the interactive user's settings at HKEY_CURRENT_USER\Software\Classes.
Further on:
If you write keys to a key under HKEY_CLASSES_ROOT, the system stores the information under HKEY_LOCAL_MACHINE\Software\Classes
The documentation doesn't define what happens when you try to write to HKEY_CLASSES_ROOT under limited privileges (i.e. a standard user can't write to HKLM), but I believe that you'll end up writing to HKCU instead.
And finally, note:
Windows Server 2003 and Windows XP/2000: Applications can register dependent COM objects to either the per-machine or per-user COM configuration store (HKEY_LOCAL_MACHINE\Software\Classes or HKEY_CURRENT_USER\Software\Classes).
So if it falls through to HKCU, you should be fine.
Caveat Implementor: Don't rely on implementation details.