Question

I am working on a file locker/unlocker application using C# on VS2010. what i want is to lock a file with a password using my application and then unlock it any time.

In fact, I used the following code to lock the file, but the file is being locked only while the application is still running; when I close the application, the file is unlocked.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Configuration;
using System.Windows.Forms;

namespace LockFile
{
    public enum LockStatus
    {
        Unlocked,
        Locked
    }

    public class LockFilePresenter
    {
        private ILockFileView view;
        private string file2Lock = string.Empty;
        private FileStream fileLockStream = null;

        public LockFilePresenter(ILockFileView view)
        {
            this.view = view;
        }

        internal void LockFile()
        {
            if (string.IsNullOrEmpty(file2Lock) || !File.Exists(file2Lock))
            {
                view.ShowMessage("Please select a path to lock.");
                return;
            }

            if (fileLockStream != null)
            {
                view.ShowMessage("The path is already locked.");
                return;
            }
            try
            {
                fileLockStream = File.Open(file2Lock, FileMode.Open);
                fileLockStream.Lock(0, fileLockStream.Length);
                view.SetStatus(LockStatus.Locked);
            }
            catch (Exception ex)
            {
                fileLockStream = null;
                view.SetStatus(LockStatus.Unlocked);
                view.ShowMessage(string.Format("An error occurred locking the path.\r\n\r\n{0}", ex.Message));
            }
        }

        internal void UnlockFile()
        {
            if (fileLockStream == null)
            {
                view.ShowMessage("No path is currently locked.");
                return;
            }
            try
            {
                using (fileLockStream)
                    fileLockStream.Unlock(0, fileLockStream.Length);
            }
            catch (Exception ex)
            {
                view.ShowMessage(string.Format("An error occurred unlocking the path.\r\n\r\n{0}", ex.Message));
            }
            finally
            {
                fileLockStream = null;
            }
            view.SetStatus(LockStatus.Unlocked);
        }

        internal void SetFile(string path)
        {
            if (ValidateFile(path))
            {
                if (fileLockStream != null)
                    UnlockFile();
                view.SetStatus(LockStatus.Unlocked);
                file2Lock = path;
                view.SetFile(path);
            }
        }

        internal bool ValidateFile(string path)
        {
            bool exists = File.Exists(path);
            if (!exists)
                view.ShowMessage("File does not exist.");
            return exists;
        }
    }
}

and

using System;
using System.Collections.Generic;
using System.Text;

namespace LockFile
{
    public interface ILockFileView
    {
        void ShowMessage(string p);
        void SetStatus(LockStatus lockStatus);
        void SetFile(string path);
    }
}

As I said previously, the application works fine during the running time, but when I close it, the locked file will be unlocked.

If anybody has any idea about how to do it, I would be grateful.

Was it helpful?

Solution

A Lock on a FileStream just means that your process has exclusive access to the file while it's active; it has nothing to do with password protecting a file.

It sounds like what you want is to encrypt a file with a password. The file class provides Encrypt/Decrypt based on the current user, or, if you want it based on your own custom password there's a sample of using some of the classes in the System.Security.Cryptography namespace to encrypt a file with a password here (instead of hard coding you would take it as input presumably) http://www.codeproject.com/Articles/26085/File-Encryption-and-Decryption-in-C

Keep in mind, doing security right is hard.

OTHER TIPS

You're using the FileStream.Lock() method to lock a specific file so that only the process running the FileStream can use it.

http://msdn.microsoft.com/en-us/library/system.io.filestream.lock.aspx

This is a mechanism designed to prevent other processes writing to a file that you are reading/writing to, and you can see this method in use with applications like Microsoft Excel.

When you close your application, the process is no longer running, and the lock on the file is disengaged.

If your goal is to prevent other applications from reading the file, you have some limited options:

  1. Encrypt the file. This will mean that an application cannot read usable information from the file without the decryption key, but there is the potential for an application to open and change the encrypted file.
  2. Save the file to a read-only media like a CD/DVD, or to removable storage that you then unplug and carry with you.

If you want to prevent other applications from modifying the file, you might look at the ReadOnly flags that Windows offers: http://msdn.microsoft.com/en-us/library/system.io.fileinfo.isreadonly.aspx

Note that these will still be insecure, as readonly flags can be ignored.

Something you need to think about is your reasoning for why you want to be restricting access to a file - that will help determine the best strategy for restricting access.

If all you need to do is make sure nothing else can read or modify the file while you've got your application locking it, the below should do the job.

If you need anything more, look into proper file encryption techniques.

Note that if you close the application the lock will no longer be in effect.

    System.IO.FileStream fileStream;

    private void LockFile(string FilePath)
    {
        fileStream = System.IO.File.Open(FilePath, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None);
        //using System.IO.FileShare.None in the above line should be sufficient, but just to go the extra mile...
        fileStream.Lock(0, fileStream.Length);
    }

    private void UnlockFile()
    {
        if (fileStream != null)
        {
            try { fileStream.Unlock(0, fileStream.Length); }
            finally { fileStream.Dispose(); }
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top