Access to registry seems to be different from different sources - c#

I am trying to add a registry key in my C# code under
HKEY_CLASSES_ROOT\*\shell\blabla
I want the user to be able to send any file to my application, kind of like Open with UltraEdit or so.
I don't have administrator rights and the users won't have administrator privileges, too.
If I am doing that in my C# code as posted below, I get a
System.UnauthorizedAccessException
Registry.SetValue("HKEY_CLASSES_ROOT\\*\\shell\\blabla", null, "FastSearch");
string path = Application.ExecutablePath;
Registry.SetValue("HKEY_CLASSES_ROOT\\*\\shell\\blabla" + "\\Command", null, path + " \"%1\"");
If I run Regedit and attempt to do it manually myself, I get a similar error:
Error! Key could not be created. Error when writing to the registry.
BUT, if I double click a *.reg file that attempts to write the SAME KEY, everything works!
So why is that?
And do I have a chance to get this done through code?
Or should I just change my code to run that *.reg file?
UPDATE:
Actually the *.reg file did not write the SAME KEY as stated above, but
HKEY_CURRENT_USER\Software\Classes\*\shell\blabla
I didn't notice that. It seems as anything added under HKEY_CURRENT_USER\Software\Classes*\shell\blabla is also added to HKEY_CLASSES_ROOT\*\shell\blabla. Sorry for the confusion.

Although the problem is solved already and the reason for successful import of *.reg file was found out also in the meantime in comparison to C# code, here is a complete answer for this question.
HKEY_CLASSES_ROOT Key (short HKCR) as described by Microsoft shows file name extension associations and COM class registration information which are effective for the current user.
The real locations in registry for those keys are:
HKEY_LOCAL_MACHINE\Software\Classes (short HKLM\Software\Classes) containing the defaults for all users using a machine and
HKEY_CURRENT_USER\Software\Classes (short HKCU\Software\Classes) containing the user specific settings which override the default settings from HKLM\Software\Classes.
A registry write to HKEY_CLASSES_ROOT is always redirected to HKLM\Software\Classes. A write access to any key in HKLM requires administrative privileges which is the reason for the error message.
Microsoft recommends to write directly to either HKLM\Software\Classes or to HKCU\Software\Classes depending on changing the defaults or the effective file associations for the current user.
Write operations to keys under HKCU do not require administrative privileges.
HKCR should be used only for reading currently effective settings for file name extension associations and COM class registration information and not for adding or changing them.

Related

Way to copy parts of windowsEventLog to a defined location? (sec,app, sys)

I need to create three seperate evtx files containing all events from the last X days found in each eventLog (security, application, system) and save those files in a defined location.
I am using c# to implement the functionality. It is also possible to execute a powershell script / bat file. If administration rights are a problem is it possible to do this for application and system only?
From my understanding:
It is not possible to create eventLogs in custom locations without changing the registry.
It is not possible to create eventLogs in the default location without Administration Rights since for creating a new eventlog file it needs to make sure that the eventlog is not already existing and it is not possible to access the security eventLog to check.
Exception message:
"The source was not found, but some or all event logs could not be searched. To create the source, you need permission to read all event logs to make sure that the new source name is unique. Inaccessible logs: Security."
Creating a evtx file with File.Create Method (String) and writing to it with File.WriteAllText Method (String, String) is also not possible
I also tried doing all of this with a powershell script but I pretty much ran into the same problems. $foo = Get-EventLog System -after (Get-Date).addays(-3) -asbaseobject
Check out this VERY useful cmdlet--which I think should have natively shipped with Windows-- Export-EventLog by Jeffrey Patton on TechNet.
It gives you a new function you can run called Export-EventLog, which even allows you to specify a custom location! It even runs on remote computers!
Export-EventLogs -ComputerName $computerName -Credential (Get-Credential) -LogName Application -Destination 'C:\LogFiles1\Application.evtx'

How to add text file in my project so that it is not visible to user..?

Sir,
I am developing an application in which i am to save some information in text file. During execution, I wish to read/write data from/to the file(.txt file). I dont want the file to be visible to user. Or if it is visible then it must be in programfile folder of the system and user could not delete the data of the file. What should i do? I tried to add the file in Resource file but could not read and write the file. PLease help me to read/write OR provide some other way to implement the same(described above).
Thanks in advance....
Don't use ProgramFiles (installation) folder:
1. File will be visible for user
2. If user won't have admin rights your app will fail on modifying the file.
Windows System folder is also question of rights. I'd advice to use system registry or appdata folder: you can get it Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData). You'll be able to write to that location without admin rights. You should create some special subfolder there (not needed, but would be convinient).
Or in registry case:
writing to registry:
string myEncrStringToSave;
Microsoft.Win32.RegistryKey key;
key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("Software\\Your_Cpecial_Key");
key.SetValue("Software\\Your_Cpecial_Key", myEncrStringToSave);
key.Close();
reading from registry:
Microsoft.Win32.RegistryKey key;
key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("Software\\Your_Cpecial_Key");
object value = key.GetValue("Software\\Your_Cpecial_Key");
if (value!=null)
string myEncryptedString = value.ToString();
key.Close();
Your_Cpecial_Key here is some identifier (like in hashtable) that allows you to get access to your data.
you could use IsolatedStorage, it's not fully hidden but at least not easily discoverable as well.
Put the file in the Windows System folder and use it from there.
You can access it without giving full path by using Environment.SpecialFolder.System.
This way user will have to work hard in order to find the file, but in case he does find you can't really prevent him from changing it as it's the same user running your program.
I am not sure if this might help you.
You may make the text file as an Embedded resource and get the same via
Assembly assm = Assembly.GetExecutingAssembly();
StreamReader aread = new StreamReader(assm.GetManifestResourceStream("Namespace.TextFile1.txt"));
So this is not accessible to the user nor available in the deployed location

Getting back "ResolveIOD" while trying to open HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\ on Windows 7?

I'm trying to get at the UserData registry subkeys on a C# 3.5 application so I can look up the installed location of an external program to start it.
Doing something like this:
RegistryKey installerKey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
and then
RegistryKey userDataKey = installerKey.OpenSubKey("UserData");
returns null; if I go back and call installerKey.GetSubKeyNames() to figure out which subkey names are present under Installer it only returns one subkey name: ResolveIOD. I haven't been able to find what only being able to find this key indicates.
regedit does not show the ResolveIOD key being there, and it shows that much more than just that one key is present - UserData, Folders, Secure, etc are all there and not returned by GetSubKeyNames() either.
This is my first time accessing anything in the Installer section of the registry hive, so I've probably done something wrong. Is there some kind of special permission I have to request in order to read these (probably sensitive, security-wise) keys from a client application, or is this generally not an acceptable thing to do on Windows 7 and I should find an alternative way of figuring out where the program is located?
Because I'm seeing this mentioned on other registry questions: This is running as a 32-bit application on 64-bit Windows.
First, to ensure you are accessing the 64-bit registry rather than the Wow6432Node sandbox, use the RegOpenKeyEx function with KEY_WOW64_64KEY (http://msdn.microsoft.com/en-us/library/ms724878%28v=vs.85%29.aspx) included as one of the access options.
pinvoke.net has a C# example: http://www.pinvoke.net/default.aspx/advapi32/RegOpenKeyEx.html
Also note that with UAC enabled, an unelevated app will, at best, only have read access to HKLM.

How does RegistryPermission works?

I am trying to check if I have write access to a specific key in the registry before displaying a form that allow the user to change some settings that are written in that key.
code sanitized for clarity
public bool CanWrite()
{
string key = #"HKEY_LOCAL_MACHINE\SOFTWARE\MyHaccpPlan, Inc.\2.0";
try
{
RegistryPermission permission = new RegistryPermission(RegistryPermissionAccess.Write, key);
permission.Demand();
return true;
}
catch(SecurityException)
{
return false;
}
}
I am running the application using a user that has read access only. The problem is that this function return true, even if the user don't have write access.
Later, a call like
Registry.SetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\MyHaccpPlan, Inc.\2.0", "Language", "fr-CA");
will fail with UnauthorizedAccessException.
How do I properly check for registry rights before attempting to write to it?
Edit
I don't want the current user to be able to write there. I want to use this registry entry as a flag that a feature in the software should be disabled. But if the user is an administrator, I want the software to allow the feature. The goal is that a network administrator could be able to preset the settings and that the users will be unable to change them.
But beside actually writing and waiting for it to crash, I want to check the security using the permission system offered in .NET if that is possible.
You shouldn't rely on .NET code access security for managing access control to the registry; let alone should you have explicit checks in your code. With that approach, the user can still use the registry editor and bypass all your access checks.
Instead, you should use proper ACLs to restrict what users can write to a key.
If you want to test at run-time whether you have access to a key, you should try to open the key for writing, and catch SecurityException (in which case the user running the application has no permission to modify the key).
mmm you can try using a tool like Lutz Roeder's Reflector for viewing the content of the Registry.SetValue Method.
Looking a bit to it, it seems to do it with next line of code:
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

How to get registry write permissions in C#

I'm trying to write to the windows registry at HKEY_CURRENT_USER\Software\appname however I keep getting a permissions error when I attempt to write to the key, I have added the following to my assembly:
[assembly: RegistryPermissionAttribute(SecurityAction.RequestMinimum, Write = #"HKEY_CURRENT_USER\\Software")]
but this has not resolved the issue, is there something else that I should be doing?
I don't suppose it's something as simple as you having opened the key without specifying that you want write access? The OpenSubKey(string) method only gives read-only access.
The RegistryPermissionAttribute is part of the Code Access Security aka CAS, this is a permission system which checks the permission you have inside of the .NET framework, these permissions are defined by the security policy. There are 4 security policies:
Enterprise - policy for a family of machines that are part of an Active Directory installation.
Machine - policy for the current machine.
User - policy for the logged on user.
AppDomain - policy for the executing application domain.
The first 3 are configured in the configuration screen in the .NET Configuration tool, and the last is configured at runtime.
The reason why I explain this first is because the RegistryPermissionAttribute only checks your .NET permissions, it does not check the Operating System permissions.
You could use the System.Security.AccessControl to check the operating system permissions, but to get the permissions you'll probably need to either elevate or impersonate.
Make sure the app runs using the user-account that has enough rights to access the registry.
I don't see an answer or resolution here. I found this question when searching for something else.
The one thing I think that may be needed is that you need to be running as administrator if you're running from the exe. If you're running from VS you'll need to make sure that VS is running as administrator. VS will show "(Administrator) in the window title if it is.
This works for me. With key already there and without it. Without any special assembly attributes.
using System;
using Microsoft.Win32;
namespace WriteToRegistry {
class Program {
static void Main(string[] args) {
const string csRootKey = #"Software\MyCompany\Test";
using (RegistryKey loRegistryKey = Registry.CurrentUser.CreateSubKey(csRootKey)) {
if (loRegistryKey == null)
throw new InvalidOperationException("Could not create sub key " + csRootKey);
loRegistryKey.SetValue("CurrentTime", DateTime.Now.ToString(), RegistryValueKind.String);
}
}
}
}
EDIT: After rereading the question it seems that the problem could be OS permissions.

Categories

Resources