I want to write a program that will encrypt an entire folder and it's sub-folders, I have no problem doing this but I would like to make the entire encryption process rather transparent by letting a user double click it and have it open as if it weren't encrypted, say if it were a picture or a word document and it'd open in it's respective application.
How can a running program of mine become notified about the opening of a target file, stop the file from opening, do what it needs to do (decrypt), followed by running the resulting decrypted file.
How can I watch a file and do this in C#? Can I watch for other interactions like the user copying a watched file (since it won't be in a watched folder, it should be decrypted i.e. it's dragged to a USB device), or for deleting a watched file (say if I want to shred a file before deletion)?
P.S. The FileSystemWatcher doesn't quite meet my needs. EDIT: What I mean is that FileSystemWatcher will tell me when a file is being opened, deleted and all those events, but it won't let me step in real quick, decrypt the file, and hand it back to the process that normally opens that file.
You can rename files, add them your own extension, like thepicture.jpg.encrypted. Set your program as a default program for this extension and handle opening them
It's impossible in C#. the bare minimum would need you to use user-mode hooks on NtCreateFile, NtOpenFile, etc. You can't achieve that in C#. That wouldn't even work properly due to kernel-mode code which may try to access your files. The proper way of doing this would be to write a I/O minifilter (in C of course).
EDIT: If you're really desperate, try EasyHook - it allows you to hook functions from C#. I haven't tried it though, and it does seem risky hooking vital functions like NtCreateFile. Plus you need a fair bit of Native API knowledge.
Are you using Windows? If so, why not use the built-in BitLocker?
See this link:
BitLocker drive encryption
If you are thinking about a competitive application to BitLocker, add a comment, as I can point you in that direction as well.
Instead of trying to reinvent the wheel, use NTFS file encryption. You can encrypt single files or entire folders or drives. Plus it's completely transparent to the user and does exactly what you asks (e.g. automatically decrypt when copying to a UBS drive, etc). Just use System.IO.File.Encrypt(string) - there couldn't be anything easier.
You can't do this from usermode.
Unfortunately the only way to do this is to write a minifilter driver. Minifilter drivers allow you to intercept IO requests to files, you can then encrypt/decrypt the files you care about on the fly.
It sounds simple, but encryption minifilter drivers are very, very, difficult to get right. You will have to end up shadowing file objects which is a real challenge. Check with www.osr.com, they have a ton of information on doing exactly what you want to do.
If you choose to go this route I would recommend getting a copy of VMWare Workstation and download VirtualKD. It will let you debug at near fire-wire speeds into a VM. I would start with x64 Win7 and get remote shares working first.
Related
I am looking for a few pointers to reaching am adequate solution to a problem/feature I need to implement/rectify in my asp.net mvc application.
My application is a LAN only interface that is run over a webserver. In this application there is a page that displays a bunch of files/folders.
I need to be able to store a set of attributes\properties about these files, and those props\attrs need to be independent of their location on the fileserver. This is my main issue, as I could easily link them to the db with the path as the primary key, but alas then as soon as the file moves their link to the db would be lost.
The types of files that need to be displayed unfortunately could be anything. .txt, .exe, media etc etc. So that provides a limiting option also from using something like the tagsharp lib.
One approach i was considering was simply storing a key somehow in the file itself, or with an ADS ( i have no experience in doing this, but am presently trying to research its potentiality).
Does anybody have any experience with this issue, and can recommend a simple approach. I am hoping i do not need to implement an ADS approach as what ive been reading so far is a little bit over my head and im not sure C# will handle the streams adequately for my needs.
Opinion based. Proposal anyway: what about an additional file which is found by a naming convention?
MyDocument.doxc
MyDomument.docx.properties
MyMovie.mp4
MyMovie.mp4.properties
When moving / renaming files, make sure you move / rename the properties file the same.
First of all thanks for taking a moment to reply.
I had considered the possibility of using a separate file. The problem is that the users of the filesystem ( which may or may not include users of the lan application ) need to be able to move/copy files independent of db application.
Therefore if a user moves a file in windows explorer, I need it to automatically move those additional properties with it. Unfortunately I cant rely on users to move those additional files on their own volition, and I cant ask users to only use the application to move files ( if i were to generate code for the program to do this ).
I work for an IT company where we all carry around flash drives that have our most used programs on them.In my spare time I am hoping to create a "main menu" item that is kind of a fun and convenient way to access these files. I am working on creating this using Visual Studio 2013 and using visual C# windows forms. I have come across a snag however that I can't seem to find a workaround for. I am by no means fluent in C#, but I need to have a button on the windows form open a file without specifying what drive it comes from. I understand that I have to specify a path, but as these will be stored on the flash drives of myself and my coworkers I cannot foresee that the path will always begin with E:. Depending on what USB slot the drive is plugged into it could be N: or F: or the like. I have provided an example below:
Using what I currently know I am opening files using this line of code:
System.Diagnostics.Process.Start("C:/Users/Myname/Desktop/Asmodeus/Anti-Virus/Anti-Virus Installers/avast_free_antivirus_setup.exe");
Is there any way possible I can have the file open simply from
System.Diagnostics.Process.Start("Asmodeus/Anti-Virus/Anti-Virus Installers/avast_free_antivirus_setup.exe");
or something of that nature?
Thanks in advance.
There must have been some mis-communication when I asked my question previously. what I am looking to do is open an executable file via a button click on the windows form using a relative path. I am not able to specify the absolute path because the application will be run from a flash drive and therefore will change depending on what USB slot it is currently inserted into.
What I am hoping to accomplish is insert a line of code that will allow me to open an executable file that is located in the \bin\debug folder along with the application itself. I have a picture for clarification but apparently do not have enough reputation to post it. Thank you and sorry for the earlier confusion.
Usually you can just use Environment.GetFolderPath (MSDN) to give you what you need. It doesn't do absolutely everything, but if you need Desktop and the like, that is plenty.
Depending on the target version of .Net, the SpecialFolders exposed are not all there. It may turn out that you need more than they provide, but in your case it doesn't sound like it.
If there is more you need that is not covered in the default, check out this project. I'm sure there are others like it, but it does a little more than the default BCL version, using the API directly. It is at least something to read and learn (and translate from vb.. use an online translator, very quick). I haven't looked at it, but it seems like you are learning this c#/.net thingy, so it might be helpful
This article is about accessing Windows special folders.
These folders include your “Favorites”, “Cookies”, system libraries and the like.
Here is code, including a large number of constant definitions, plus documentation,
allowing access to and creation of these folders.
I would like to either host a virtual drive and intercept the I/O, or intercept I/O calls to certain folders on a hard drive, and do arbitrary things to that call like write the file to a 2nd location. For example, if Notepad.exe writes a file to C:\Data\test.txt - I would like to have access to that file name, and the data of the file. Likewise, I would like to run arbitrary code when any user attempts to read C:\Data\test.txt or attempts to get a directory listing for C:\Data.
Ideally I want to have a handler for when a file is: created, updated, deleted, or opened - and when someone does a directory listing (from command-line or from the Shell).
I can do the write part with FileSystemWatcher - but I can't intercept disk "reads". So, I next looked into MS Detours and EasyHook. That won't really work because I'd need to monitor every single process on the computer and hook to OpenFile on ALL of them. I don't want to use a Shell Extension because this behavior needs to exist from the command-line too. So, that leaves either writing a File System MiniFilter driver - or writing my own installable file system in C++.
I can have some portion of this in C++ - although the driver stuff is a bit over my head, but ultimately most of the rest of code should be in C#, ideally.
Is there some straightforward way to intercept I/O to a specific folder or virtual drive? If the answer is with EasyHook or a MiniFilter, does anyone have any samples? EasyHook in particular only has samples from the late-2000s and the API has changed since then. Thanks!
Looks like an XY problem. What you seem to want are reparse point handlers.
Your example of "writing a file to another location" is just a link, and those already exist. Implemented by a standard reparse point handler.
You don't specify exactly what else you want to do, but similar things can be done by custom reparse point handlers. In short, a reparse point is a small bit of data in place of a file, which (1) specifies which handler should be called, and (2) provides custom data to that handler. For instance, the actual location of the file. Since it's custom data, you can use any format you like.
I am looking for a programmatic way to copy files from one network drive to another. I have created a program that does a simple copy but this is not enough as the line is not reliable and the files ends up being corrupted. Is there a technology that syncs the folders and does a sum-check or something like that.
I need it to be a c# app as I need to know when the copy is completed so I can process the files on the other side. I am using windows services to co-ordinate this.
I'm just looking for someone to point me in the right direction with tutorials if necessary.
What you are looking for is Robocopy (aka Robust Copy), it is built in to windows Vista and newer and it has features to retry on network failure.
One down side is there is no "Verify" functionality built in, but if you need to you can use a 3rd party file hashing program and put the copy in a script that verifies the hashes after the copy completes.
Here is a query that copies all files and sub-folders in a restartable mode, if a copy fails it will re-try 1,000,000 times by default waiting 30 seconds between tries. (you can change that with /r:<N> and /w:<N> where <N> is a number)
robocopy C:\SourceFolder \\DestComputer\DestFolder /zb /e
The only time I have ever done anything like this has been during the deploy process to distributed servers. In that instance I zipped the files, moved and unzipped them using PSEXEC.
If I were you, I would begin by figuring out how to zip the files (To prevent the corruption issues you have described) and then worry about how to move them.
I am working on an application that keeps track and uses files stored on the file system. Users are allowed to open, create, delete and move files in the file system. Meanwhile my application is not constantly running so I can't keep track of all changes real-time. Afterwards my application has to find out what file is whom (i.c. as identified in my application).
The most preferred solution for the users is that the application solves every change itself. Each user-interaction is less preferred.
One of my ideas was to use an attribute of a file and assign a key-value to it so when it has been identified once, it can always been recognized afterwards. But I don't know if there is such an attribute. This article didn't give much hope: There is in Windows file systems a pre computed hash for each file?.
Does somebody know if there is such an attribute I can use? And how can I used it in C#?
Is there anyone who is running up against this problem? And how did you solve it?
I'd like to hear good suggestions.
regards, Jaap
If your files don't leave NTFS, this is easily achievable by alternative data streams, where you can store your data along with files. This is more-or-less good article about ADS: http://www.flexhex.com/docs/articles/alternate-streams.phtml
There is another suitable method - it's very efficient, but also very complicated to use, it requires quite good knowledge about NTFS internals - USN Change Journal; see http://msdn.microsoft.com/en-us/library/windows/desktop/aa363798.aspx. With USN Change Journal, you can "get" very efficiently all files that were changed (even all change events) within specified time period.
Nevertheless, if your files leave NTFS realm, e.g. if it's copied to FAT32, contents of ADS is lost.
Relying on a File attribute is "dangerous" in that some user could alter the attribute while your program isn't running. This could lead you to believe that a certain file is (or isn't) tracked by the program while it really isn't.
I would suggest to keep track of the files in a database, XML, or some other file. When your application starts you read the file/db and check for new/deleted/editted files.
You could store a Hash of the files to find out if a file has been moved/editted. Keeping track of files that are moved AND editted is going to be pretty difficult. (I have no clue how you could achieve it)
PS: Have you considered making your application a Windows service? Having the file-management running in the background no matter if the GUI part of your application is running or not?