Click here to Skip to main content
15,885,435 members
Articles / Desktop Programming / WPF

Wrap Panel Virtualization

Rate me:
Please Sign up or sign in to vote.
4.95/5 (18 votes)
2 Jan 2012CPOL2 min read 53.2K   5.6K   41  
WrapPanel doesn't support virtualization. But we can improve the performance by simulating virtualization.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

using ComTypes = System.Runtime.InteropServices.ComTypes;

namespace Dokan
{
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    struct BY_HANDLE_FILE_INFORMATION
    {
        public uint dwFileAttributes;
        public ComTypes.FILETIME ftCreationTime;
        public ComTypes.FILETIME ftLastAccessTime;
        public ComTypes.FILETIME ftLastWriteTime;
        public uint dwVolumeSerialNumber;
        public uint nFileSizeHigh;
        public uint nFileSizeLow;
        public uint dwNumberOfLinks;
        public uint nFileIndexHigh;
        public uint nFileIndexLow;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    struct DOKAN_FILE_INFO
    {
        public ulong Context;
        public ulong DokanContext;
        public IntPtr DokanOptions;
        public uint ProcessId;
        public byte IsDirectory;
        public byte DeleteOnClose;
        public byte PagingIo;
        public byte SynchronousIo;
        public byte Nocache;
        public byte WriteToEndOfFile;
    }

    [Flags]
    enum SECURITY_INFORMATION : uint
    {
        OWNER_SECURITY_INFORMATION = 0x00000001,
        GROUP_SECURITY_INFORMATION = 0x00000002,
        DACL_SECURITY_INFORMATION = 0x00000004,
        SACL_SECURITY_INFORMATION = 0x00000008,
        UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000,
        UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000,
        PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000,
        PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
    }

    [StructLayoutAttribute(LayoutKind.Sequential, Pack = 4)]
    struct SECURITY_DESCRIPTOR
    {
        public byte revision;
        public byte size;
        public short control;
        public IntPtr owner;
        public IntPtr group;
        public IntPtr sacl;
        public IntPtr dacl;
    }

    class Proxy
    {
        private DokanOperations operations_;
        private ArrayList array_;
        private Dictionary<ulong, DokanFileInfo> infoTable_;
        private ulong infoId_ = 0;
        private object infoTableLock_ = new object();
        private DokanOptions options_;

        public Proxy(DokanOptions options, DokanOperations operations)
        {
            operations_ = operations;
            options_ = options;
            array_ = new ArrayList();
            infoTable_ = new Dictionary<ulong, DokanFileInfo>();
        }

        private void ConvertFileInfo(ref DOKAN_FILE_INFO rawInfo, DokanFileInfo info)
        {
            info.IsDirectory = rawInfo.IsDirectory == 1;
            info.ProcessId = rawInfo.ProcessId;
            info.PagingIo = rawInfo.PagingIo == 1;
            info.DeleteOnClose = rawInfo.DeleteOnClose == 1;
            info.SynchronousIo = rawInfo.SynchronousIo == 1;
            info.Nocache = rawInfo.Nocache == 1;
            info.WriteToEndOfFile = rawInfo.WriteToEndOfFile == 1;
        }

        private DokanFileInfo GetNewFileInfo(ref DOKAN_FILE_INFO rawFileInfo)
        {
            DokanFileInfo fileInfo = new DokanFileInfo(rawFileInfo.DokanContext);

            lock (infoTableLock_)
            {
                fileInfo.InfoId = ++infoId_;

                rawFileInfo.Context = fileInfo.InfoId;
                ConvertFileInfo(ref rawFileInfo, fileInfo);
                // to avoid GC
                infoTable_[fileInfo.InfoId] = fileInfo;
            }
            return fileInfo;
        }

        private DokanFileInfo GetFileInfo(ref DOKAN_FILE_INFO rawFileInfo)
        {
            DokanFileInfo fileInfo = null;
            lock (infoTableLock_)
            {
                if (rawFileInfo.Context != 0)
                {
                    infoTable_.TryGetValue(rawFileInfo.Context, out fileInfo);
                }

                if (fileInfo == null)
                {
                    // bug?
                    fileInfo = new DokanFileInfo(rawFileInfo.DokanContext);
                }
                ConvertFileInfo(ref rawFileInfo, fileInfo);
            }
            return fileInfo;
        }
      
        private string GetFileName(IntPtr fileName)
        {
            return Marshal.PtrToStringUni(fileName);
        }


        private const uint GENERIC_READ = 0x80000000;
        private const uint GENERIC_WRITE = 0x40000000;
        private const uint GENERIC_EXECUTE = 0x20000000;
        
        private const uint FILE_READ_DATA = 0x0001;
        private const uint FILE_READ_ATTRIBUTES = 0x0080;
        private const uint FILE_READ_EA = 0x0008;
        private const uint FILE_WRITE_DATA = 0x0002;
        private const uint FILE_WRITE_ATTRIBUTES = 0x0100;
        private const uint FILE_WRITE_EA = 0x0010;

        private const uint FILE_SHARE_READ = 0x00000001;
        private const uint FILE_SHARE_WRITE = 0x00000002;
        private const uint FILE_SHARE_DELETE = 0x00000004;

        private const uint CREATE_NEW = 1;
        private const uint CREATE_ALWAYS = 2;
        private const uint OPEN_EXISTING = 3;
        private const uint OPEN_ALWAYS = 4;
        private const uint TRUNCATE_EXISTING = 5;
        
        private const uint FILE_ATTRIBUTE_ARCHIVE = 0x00000020;
        private const uint FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
        private const uint FILE_ATTRIBUTE_HIDDEN = 0x00000002;
        private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
        private const uint FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000;
        private const uint FILE_ATTRIBUTE_OFFLINE = 0x00001000;
        private const uint FILE_ATTRIBUTE_READONLY = 0x00000001;
        private const uint FILE_ATTRIBUTE_SYSTEM = 0x00000004;
        private const uint FILE_ATTRIBUTE_TEMPORARY = 0x00000100;

        
        public delegate int CreateFileDelegate(
            IntPtr rawFilName,
            uint rawAccessMode,
            uint rawShare,
            uint rawCreationDisposition,
            uint rawFlagsAndAttributes,
            ref DOKAN_FILE_INFO dokanFileInfo);

        public int CreateFileProxy(
            IntPtr rawFileName,
            uint rawAccessMode,
            uint rawShare,
            uint rawCreationDisposition,
            uint rawFlagsAndAttributes,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                DokanFileInfo info = GetNewFileInfo(ref rawFileInfo);
                
                FileAccess access = FileAccess.Read;
                FileShare share = FileShare.None;
                FileMode mode = FileMode.Open;
                FileOptions options = FileOptions.None;

                if ((rawAccessMode & FILE_READ_DATA) != 0 && (rawAccessMode & FILE_WRITE_DATA) != 0)
                {
                    access = FileAccess.ReadWrite;
                }
                else if ((rawAccessMode & FILE_WRITE_DATA) != 0)
                {
                    access = FileAccess.Write;
                }
                else
                {
                    access = FileAccess.Read;
                }

                if ((rawShare & FILE_SHARE_READ) != 0)
                {
                    share = FileShare.Read;
                }

                if ((rawShare & FILE_SHARE_WRITE) != 0)
                {
                    share |= FileShare.Write;
                }

                if ((rawShare & FILE_SHARE_DELETE) != 0)
                {
                    share |= FileShare.Delete;
                }

                switch (rawCreationDisposition)
                {
                    case CREATE_NEW:
                        mode = FileMode.CreateNew;
                        break;
                    case CREATE_ALWAYS:
                        mode = FileMode.Create;
                        break;
                    case OPEN_EXISTING:
                        mode = FileMode.Open;
                        break;
                    case OPEN_ALWAYS:
                        mode = FileMode.OpenOrCreate;
                        break;
                    case TRUNCATE_EXISTING:
                        mode = FileMode.Truncate;
                        break;
                }

                int ret = operations_.CreateFile(file, access, share, mode, options, info);

                if (info.IsDirectory)
                    rawFileInfo.IsDirectory = 1;

                return ret;
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -2;
            }

        }

        ////

        public delegate int OpenDirectoryDelegate(
            IntPtr FileName,
            ref DOKAN_FILE_INFO FileInfo);

        public int OpenDirectoryProxy(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                DokanFileInfo info = GetNewFileInfo(ref rawFileInfo);
                return operations_.OpenDirectory(file, info);

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int CreateDirectoryDelegate(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int CreateDirectoryProxy(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                DokanFileInfo info = GetNewFileInfo(ref rawFileInfo);
                return operations_.CreateDirectory(file, info);

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int CleanupDelegate(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int CleanupProxy(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);
                return operations_.Cleanup(file, GetFileInfo(ref rawFileInfo));

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int CloseFileDelegate(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int CloseFileProxy(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);
                DokanFileInfo info = GetFileInfo(ref rawFileInfo);

                int ret = operations_.CloseFile(file, info);

                rawFileInfo.Context = 0;

                lock (infoTableLock_)
                {
                    infoTable_.Remove(info.InfoId);
                }
                return ret;

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int ReadFileDelegate(
            IntPtr rawFileName,
            IntPtr rawBuffer,
            uint rawBufferLength,
            ref uint rawReadLength,
            long rawOffset,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int ReadFileProxy(
            IntPtr rawFileName,
            IntPtr rawBuffer,
            uint rawBufferLength,
            ref uint rawReadLength,
            long rawOffset,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                byte[] buf = new Byte[rawBufferLength];

                uint readLength = 0;
                int ret = operations_.ReadFile(
                    file, buf, ref readLength, rawOffset, GetFileInfo(ref rawFileInfo));
                if (ret == 0)
                {
                    rawReadLength = readLength;
                    Marshal.Copy(buf, 0, rawBuffer, (int)rawBufferLength);
                }
                return ret;

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int WriteFileDelegate(
            IntPtr rawFileName,
            IntPtr rawBuffer,
            uint rawNumberOfBytesToWrite,
            ref uint rawNumberOfBytesWritten,
            long rawOffset,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int WriteFileProxy(
            IntPtr rawFileName,
            IntPtr rawBuffer,
            uint rawNumberOfBytesToWrite,
            ref uint rawNumberOfBytesWritten,
            long rawOffset,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                Byte[] buf = new Byte[rawNumberOfBytesToWrite];
                Marshal.Copy(rawBuffer, buf, 0, (int)rawNumberOfBytesToWrite);

                uint bytesWritten = 0;
                int ret = operations_.WriteFile(
                    file, buf, ref bytesWritten, rawOffset, GetFileInfo(ref rawFileInfo));
                if (ret == 0)
                    rawNumberOfBytesWritten = bytesWritten;
                return ret;

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int FlushFileBuffersDelegate(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int FlushFileBuffersProxy(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);
                int ret = operations_.FlushFileBuffers(file, GetFileInfo(ref rawFileInfo));
                return ret;

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }
       
        ////

        public delegate int GetFileInformationDelegate(
            IntPtr FileName,
            ref BY_HANDLE_FILE_INFORMATION HandleFileInfo,
            ref DOKAN_FILE_INFO FileInfo);

        public int GetFileInformationProxy(
            IntPtr rawFileName,
            ref BY_HANDLE_FILE_INFORMATION rawHandleFileInformation,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                FileInformation fi = new FileInformation();

                int ret = operations_.GetFileInformation(file, fi, GetFileInfo(ref rawFileInfo));

                if (ret == 0)
                {
                    rawHandleFileInformation.dwFileAttributes = (uint)fi.Attributes;

                    rawHandleFileInformation.ftCreationTime.dwHighDateTime =
                        (int)(fi.CreationTime.ToFileTime() >> 32);
                    rawHandleFileInformation.ftCreationTime.dwLowDateTime =
                        (int)(fi.CreationTime.ToFileTime() & 0xffffffff);

                    rawHandleFileInformation.ftLastAccessTime.dwHighDateTime =
                        (int)(fi.LastAccessTime.ToFileTime() >> 32);
                    rawHandleFileInformation.ftLastAccessTime.dwLowDateTime =
                        (int)(fi.LastAccessTime.ToFileTime() & 0xffffffff);

                    rawHandleFileInformation.ftLastWriteTime.dwHighDateTime =
                        (int)(fi.LastWriteTime.ToFileTime() >> 32);
                    rawHandleFileInformation.ftLastWriteTime.dwLowDateTime =
                        (int)(fi.LastWriteTime.ToFileTime() & 0xffffffff);

                    rawHandleFileInformation.nFileSizeLow =
                        (uint)(fi.Length & 0xffffffff);
                    rawHandleFileInformation.nFileSizeHigh =
                        (uint)(fi.Length >> 32);
                }

                return ret;

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }

        }

        ////

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
        struct WIN32_FIND_DATA
        {
            public FileAttributes dwFileAttributes;
            public ComTypes.FILETIME ftCreationTime;
            public ComTypes.FILETIME ftLastAccessTime;
            public ComTypes.FILETIME ftLastWriteTime;
            public uint nFileSizeHigh;
            public uint nFileSizeLow;
            public uint dwReserved0;
            public uint dwReserved1;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string cFileName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
            public string cAlternateFileName;
        }

        private delegate int FILL_FIND_DATA(
            ref WIN32_FIND_DATA rawFindData,
            ref DOKAN_FILE_INFO rawFileInfo);

        public delegate int FindFilesDelegate(
            IntPtr rawFileName,
            IntPtr rawFillFindData, // function pointer
            ref DOKAN_FILE_INFO rawFileInfo);

        public int FindFilesProxy(
            IntPtr rawFileName,
            IntPtr rawFillFindData, // function pointer
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                ArrayList files = new ArrayList();
                int ret = operations_.FindFiles(file, files, GetFileInfo(ref rawFileInfo));

                FILL_FIND_DATA fill = (FILL_FIND_DATA)Marshal.GetDelegateForFunctionPointer(
                    rawFillFindData, typeof(FILL_FIND_DATA));

                if (ret == 0)
                {
                    IEnumerator entry = files.GetEnumerator();
                    while (entry.MoveNext())
                    {
                        FileInformation fi = (FileInformation)(entry.Current);
                        WIN32_FIND_DATA data = new WIN32_FIND_DATA();
                        //ZeroMemory(&data, sizeof(WIN32_FIND_DATAW));

                        data.dwFileAttributes = fi.Attributes;

                        data.ftCreationTime.dwHighDateTime =
                            (int)(fi.CreationTime.ToFileTime() >> 32);
                        data.ftCreationTime.dwLowDateTime =
                            (int)(fi.CreationTime.ToFileTime() & 0xffffffff);

                        data.ftLastAccessTime.dwHighDateTime =
                            (int)(fi.LastAccessTime.ToFileTime() >> 32);
                        data.ftLastAccessTime.dwLowDateTime =
                            (int)(fi.LastAccessTime.ToFileTime() & 0xffffffff);

                        data.ftLastWriteTime.dwHighDateTime =
                            (int)(fi.LastWriteTime.ToFileTime() >> 32);
                        data.ftLastWriteTime.dwLowDateTime =
                            (int)(fi.LastWriteTime.ToFileTime() & 0xffffffff);

                        data.nFileSizeLow =
                            (uint)(fi.Length & 0xffffffff);
                        data.nFileSizeHigh =
                            (uint)(fi.Length >> 32);

                        data.cFileName = fi.FileName;

                        fill(ref data, ref rawFileInfo);
                    }

                }
                return ret;

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }

        }

        ////

        public delegate int SetEndOfFileDelegate(
            IntPtr rawFileName,
            long rawByteOffset,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int SetEndOfFileProxy(
            IntPtr rawFileName,
            long rawByteOffset,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                return operations_.SetEndOfFile(file, rawByteOffset, GetFileInfo(ref rawFileInfo));

            }
            catch (Exception e)
            {

                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }


        public delegate int SetAllocationSizeDelegate(
            IntPtr rawFileName,
            long rawLength,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int SetAllocationSizeProxy(
            IntPtr rawFileName,
            long rawLength,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                return operations_.SetAllocationSize(file, rawLength, GetFileInfo(ref rawFileInfo));

            }
            catch (Exception e)
            {

                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }


        ////

        public delegate int SetFileAttributesDelegate(
            IntPtr rawFileName,
            uint rawAttributes,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int SetFileAttributesProxy(
            IntPtr rawFileName,
            uint rawAttributes,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                FileAttributes attr = (FileAttributes)rawAttributes;
                return operations_.SetFileAttributes(file, attr, GetFileInfo(ref rawFileInfo));

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int SetFileTimeDelegate(
            IntPtr rawFileName,
            ref ComTypes.FILETIME rawCreationTime,
            ref ComTypes.FILETIME rawLastAccessTime,
            ref ComTypes.FILETIME rawLastWriteTime,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int SetFileTimeProxy(
            IntPtr rawFileName,
            ref ComTypes.FILETIME rawCreationTime,
            ref ComTypes.FILETIME rawLastAccessTime,
            ref ComTypes.FILETIME rawLastWriteTime,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                long time;

                time = ((long)rawCreationTime.dwHighDateTime << 32) + (uint)rawCreationTime.dwLowDateTime;
                DateTime ctime = DateTime.FromFileTime(time);
                
                if (time == 0)
                    ctime = DateTime.MinValue;

                time = ((long)rawLastAccessTime.dwHighDateTime << 32) + (uint)rawLastAccessTime.dwLowDateTime;
                DateTime atime = DateTime.FromFileTime(time);

                if (time == 0)
                    atime = DateTime.MinValue;

                time = ((long)rawLastWriteTime.dwHighDateTime << 32) + (uint)rawLastWriteTime.dwLowDateTime;
                DateTime mtime = DateTime.FromFileTime(time);

                if (time == 0)
                    mtime = DateTime.MinValue;

                return operations_.SetFileTime(
                    file, ctime, atime, mtime, GetFileInfo(ref rawFileInfo));

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int DeleteFileDelegate(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int DeleteFileProxy(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);

                return operations_.DeleteFile(file, GetFileInfo(ref rawFileInfo));

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int DeleteDirectoryDelegate(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int DeleteDirectoryProxy(
            IntPtr rawFileName,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);
                return operations_.DeleteDirectory(file, GetFileInfo(ref rawFileInfo));

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int MoveFileDelegate(
            IntPtr rawFileName,
            IntPtr rawNewFileName,
            int rawReplaceIfExisting,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int MoveFileProxy(
            IntPtr rawFileName,
            IntPtr rawNewFileName,
            int rawReplaceIfExisting,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);
                string newfile = GetFileName(rawNewFileName);

                return operations_.MoveFile(
                    file, newfile, rawReplaceIfExisting != 0 ? true : false,
                    GetFileInfo(ref rawFileInfo));

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int LockFileDelegate(
            IntPtr rawFileName,
            long rawByteOffset,
            long rawLength,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int LockFileProxy(
            IntPtr rawFileName,
            long rawByteOffset,
            long rawLength,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);
                return operations_.LockFile(
                    file, rawByteOffset, rawLength, GetFileInfo(ref rawFileInfo));

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int UnlockFileDelegate(
            IntPtr rawFileName,
            long rawByteOffset,
            long rawLength,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int UnlockFileProxy(
            IntPtr rawFileName,
            long rawByteOffset,
            long rawLength,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                string file = GetFileName(rawFileName);
                return operations_.UnlockFile(
                    file, rawByteOffset, rawLength, GetFileInfo(ref rawFileInfo));

            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        ////

        public delegate int GetDiskFreeSpaceDelegate(
            ref ulong rawFreeBytesAvailable,
            ref ulong rawTotalNumberOfBytes,
            ref ulong rawTotalNumberOfFreeBytes,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int GetDiskFreeSpaceProxy(
            ref ulong rawFreeBytesAvailable,
            ref ulong rawTotalNumberOfBytes,
            ref ulong rawTotalNumberOfFreeBytes,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                return operations_.GetDiskFreeSpace(
                    ref rawFreeBytesAvailable,
                    ref rawTotalNumberOfBytes,
                    ref rawTotalNumberOfFreeBytes,
                    GetFileInfo(ref rawFileInfo));
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        public delegate int GetVolumeInformationDelegate(
            IntPtr rawVolumeNameBuffer,
            uint rawVolumeNameSize,
            ref uint rawVolumeSerialNumber,
            ref uint rawMaximumComponentLength,
            ref uint rawFileSystemFlags,
            IntPtr rawFileSystemNameBuffer,
            uint rawFileSystemNameSize,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int GetVolumeInformationProxy(
            IntPtr rawVolumeNameBuffer,
            uint rawVolumeNameSize,
            ref uint rawVolumeSerialNumber,
            ref uint rawMaximumComponentLength,
            ref uint rawFileSystemFlags,
            IntPtr rawFileSystemNameBuffer,
            uint rawFileSystemNameSize,
            ref DOKAN_FILE_INFO FileInfo)
        {
            byte[] volume = System.Text.Encoding.Unicode.GetBytes(options_.VolumeLabel);
            Marshal.Copy(volume, 0, rawVolumeNameBuffer, Math.Min((int)rawVolumeNameSize, volume.Length));
            rawVolumeSerialNumber = 0x19831116;
            rawMaximumComponentLength = 256;

            // FILE_CASE_SENSITIVE_SEARCH | 
            // FILE_CASE_PRESERVED_NAMES |
            // FILE_UNICODE_ON_DISK
            rawFileSystemFlags = 7;

            byte[] sys = System.Text.Encoding.Unicode.GetBytes("DOKAN");
            Marshal.Copy(sys, 0, rawFileSystemNameBuffer, Math.Min((int)rawFileSystemNameSize, sys.Length));
            return 0;
        }


        public delegate int UnmountDelegate(
            ref DOKAN_FILE_INFO rawFileInfo);

        public int UnmountProxy(
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            try
            {
                return operations_.Unmount(GetFileInfo(ref rawFileInfo));
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
                return -1;
            }
        }

        public delegate int GetFileSecurityDelegate(
            IntPtr rawFileName,
            ref SECURITY_INFORMATION rawRequestedInformation,
            ref SECURITY_DESCRIPTOR rawSecurityDescriptor,
            uint rawSecurityDescriptorLength,
            ref uint rawSecurityDescriptorLengthNeeded,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int GetFileSecurity(
            IntPtr rawFileName,
            ref SECURITY_INFORMATION rawRequestedInformation,
            ref SECURITY_DESCRIPTOR rawSecurityDescriptor,
            uint rawSecurityDescriptorLength,
            ref uint rawSecurityDescriptorLengthNeeded,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            return -1;
        }

        public delegate int SetFileSecurityDelegate(
            IntPtr rawFileName,
            ref SECURITY_INFORMATION rawSecurityInformation,
            ref SECURITY_DESCRIPTOR rawSecurityDescriptor,
            uint rawSecurityDescriptorLength,
            ref DOKAN_FILE_INFO rawFileInfo);

        public int SetFileSecurity(
            IntPtr rawFileName,
            ref SECURITY_INFORMATION rawSecurityInformation,
            ref SECURITY_DESCRIPTOR rawSecurityDescriptor,
            ref uint rawSecurityDescriptorLengthNeeded,
            ref DOKAN_FILE_INFO rawFileInfo)
        {
            return -1;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) KAZ Software Limited
Bangladesh Bangladesh
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions