i'm making a small project. it's Windows Form Application. i got some sources in a folder (C:/sources). When my program runs, it uses sources from the folder. Currently i can edit the folder by windows explorer, it can cause errors for my program. So i want to lock the folder (C:/sources) from being edited/renamed/deleted when my program runs. How to do so?
EDIT;
Is it possible to show a message like this when user has tried to edit the folder:
"the action cannot be completed because the folder or a file in it is open in another program"
the program that we are talking about is mine..
There are a couple of approaches that you could venture and they vary in difficulty of implementation. It all depends on how important this task is for you. But, before discussing these options; can't you embed those resources in your WinForms application instead? If this is not an option then you can do one of the following:
Write a device driver that can prohibit the access of such resources if your application is running. There are fallbacks to this approach. For example one can impersonate your application by having the same name. But, am not getting in to too much details in trying to break any approach as I am trying to address possible solutions to the current problem. There are different types of drivers that you can consider. Probably the simplest form of this approach would be to implement a mini-filter driver.
Hook certain API's like CreateFile(), NtCreateFile(), ZwCreateFile() although there are many ways to circumvent such mechanism of defense. But, again we are only venturing what you can do to address this constraint of yours.
Open these resources directly from your application and lock it exclusively. For example:
File.Open("test.txt", FileMode.Open, FileAccess.Read, FileShare.None);
as this will result in people getting the message that you desire if they try to open the file.
Maybe you can give more information on what these resources are and we can help you determine which is the best way to protect your files in a reasonable fashion?
Although I don't believe it's the best idea to have files that are critical to the application in a open area like the C: drive, I would look into NTFS file permissions and set the folder to read only, but this wont stop administrative users
See these two posts
restrict access to folder outside of program c#
Setting NTFS permissions in C#.NET
Related
It may seem like this question has been asked a thousand times before, but I can't find an answer that actually points to a path that is common AND writable for all users.
In any case - in my application the users can download some fairly large data files that need to be accessible to the application after download. The application is used in multi user enviroments, so I'm not interested in storing a copy of the downloaded files for each user.
So far I've been using CommonApplicationData (C:\ProgramData\[Vendor]\[Application] created using Wix installer), but I've recently learned that this is meant as readonly storage and several users have experienced issues with this because CommonApplicationData is write protected.
I've been checking different options and the only viable one I have found so far is the %public% folder (https://blogs.msdn.microsoft.com/cjacks/2008/02/05/where-should-i-write-program-data-instead-of-program-files/).
Is this the best/correct place to put the files or is there another solution? Needs to work in Windows XP/Vista/7/8/10.
CommonApplicationData is indeed the correct place to store this data, unless the users should be able to see them as documents to double-click.
When you create the folder (or the individual files or subfolders within it) you should set the permissions according to your needs.
One alternative approach, to provide better cross-user security, is to install a system service to download and install these files on the users behalf.
Is it possible to create a C#.net (or a .bat) program that will automatically run upon access of a specific folder?
Thanks.
Windows 7/8/10: Not if you don't have a background process running that checks for the folder to be opened. So no, considering you want this to behave autonomously, I'm afraid not.
Windows XP: Yes, but let's not do that. This brings security issues and the only implementation I know of is the MS32DLL virus that would do this to partition roots.
EDIT: Based on your last comment (in particular the one that elaborates the context being data security), this is the wrong approach. There are multiple ways around this (think of any third party file browser, even DOS will work) and having this feature in Windows would leave it very vulnerable to attacks. Instead, you should read into applying NTFS permissions and file encryption.
My application basically creates an XML file in C:\ProgramData\MyAppFolder and dumps config settings in it.
I need to allow even standard users to have permission to add or delete settings to these config files. Right now I see that standard users only have read/execute permission but not "Full Control".
I've seen other questions being answered with ways to modify permissions to that particular folder but I don't want to change the default permission level, since it might be reset by a system admin.
If C:\ProgramData can't give that access to all users, is there any folder that best suits the needs of application?
EDIT:
My initial question might be misleading. I don't want to give rights to users, but rather allow the application to modify the XML file when it is run by all users.
DECISION:
I think changing the permissions while creating the folder in ProgramData is the only option.
And if that's not possible, CommonDocuments is the way to go.
Thanks Eve.
I would use a folder in the Environment.SpecialFolder enum.
Example:
var path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
Assuming you have an installer for your application, your installer can create a subfolder in the common appdata directory (aka C:\ProgramData) which your application will have read/write access to. Depending on your choice of installation technology you can set the permissions on that folder as well, although that may be overkill. I know with WiX basically all you have to do is a per-machine installation and make sure that sub folder gets created.
Users should not be allowed to write arbitrary data to this directory. This is equivalent to regular users being able to modify the C:\Users\AllUsers directory. If users need to be modifying this directory you have serious design flaws and should reconsider this approach. What should happen is the users are given GUI interface to interact with that manipulates these values behind the scenes without giving them direct access, similar to how getters/setters work in most programming languages. Needless to say it is a very large security hole when regular users can corrupt a system for other users.
UPDATE
I don't want to give users direct access to the file. My question
might have been misleading. I want to allow the program to have full
control on the file even when it being run by all users. I'm actually
doing this: "users are given GUI interface to interact with that
manipulates these values behind the scenes without giving them direct
access"
This article which has far too much information to post here, will provide details on remaining secure as to not leak permissions. The first thing you want to do is make sure that your application user is in its own group and cannot login/have any special permissions. What you can than do is have this group added to the directory with write permissions, which would allow this application to perform these tasks. If that is not possible you will need to work within UAC to not break the security of the system as is detailed in the article above.
Second Update
Thanks for the link. Any suggestions on some other folder which can do
the job, rather than messing with the permissions?
Sure you can write it into the directory where the application is written to, i.e. C:\Program Files\Some Awesome Program, this keeps everything in one place, and you only have to worry about your user/group and anything that the person who installed it has allowed for. It also prevents other people from messing with it unless of course they are administrators.
I see that this question has been asked many times in stackoverflow, as well as in other places. The questioners solved their problem by different methods. Most of these solutions are around how they designed their applications and locking level on the files.
I understand that Windows provides Read/Write protection in different ways. But, still, if the file is on my disk, and being an administrator, can't I read the contents of the locked file forcefully? Any pointers on how I can achieve that would be greatly helpful.
The file in question is totally inaccessible to other processes through C# .NET APIs. Looks like its readlocked.
Thanks.
If file is locked from your app, you have to close all buffers/streams or whatever you have opened before.
If file is locked from something else the only solution I know is to use Unlocker, which can be run even without GUI using some console param (so using Process class in C#).
But be careful to walk this way, because you could corrupt file and create some memory leak closing with brute force opened handles and probably application that was using them.
I'm not sure if the question's title makes sense, and I'm sorry if it doesn't; I didn't really know what to title it.. Anyway, is there a way to make your program track the viewing of a folder?
What I'm trying to achieve: Windows 7 Home Premium doesn't allow encryption. So, I made a folder inside my user directory, and set it to hidden. Although, you can easily find it by changing windows settings.. So, is there a way to make a program pull up a window if the user tries to access that certain folder?
I don't think you can detect the "opening" of a folder.
Instead, you may want to set a FileSystemWatcher to detect any file access to the files in that particular folder.
Hope this helps.
First of all, I have to wonder why you're not just setting an ACL on the directory to prevent access.
However, it sounds like you want to find when somebody is accessing a particular directory. To do this, you enable filesystem auditing, then set the audit ACL to generate audit entries for "List folder". This will cause entries to be generated in the Security Event Log whenever the directory is viewed.
Now you just have to write a program that watches the Security event log looking for entries indicating that somebody has listed the directory in question and take action as necessary.
Well, there is an article on code project describing how you can hook into windows system calls: http://www.codeproject.com/KB/system/hooksys.aspx - it's not simple though (and also not C#) and has the potential to screw with your system but if it might be a fun project to work on.
A simpler option would be: Use a 3rd party desktop encryption tool - not much programming involved here but it might do the job better than anything else.