예제 #1
0
        public static void CreateSparse(string filename, long length)
        {
            if (!SupportsSparse)
                return;

            // Ensure we have the full path
            filename = Path.GetFullPath(filename);
            try
            {
                if (!CanCreateSparse(filename))
                    return;

                // Create a file with the sparse flag enabled

                uint bytesReturned = 0;
                uint access = 0x40000000;         // GenericWrite
                uint sharing = 0;                 // none
                uint attributes = 0x00000080;     // Normal
                uint creation = 1;                // Only create if new

                using (SafeFileHandle handle = CreateFileW(filename, access, sharing, IntPtr.Zero, creation, attributes, IntPtr.Zero))
                {
                    // If we couldn't create the file, bail out
                    if (handle.IsInvalid)
                        return;

                    // If we can't set the sparse bit, bail out
                    if (!DeviceIoControl(handle, FSCTL_SET_SPARSE, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero))
                        return;

                    // Tell the filesystem to mark bytes 0 -> length as sparse zeros
                    FILE_ZERO_DATA_INFORMATION data = new FILE_ZERO_DATA_INFORMATION(0, length);
                    uint structSize = (uint)Marshal.SizeOf(data);
                    IntPtr ptr = Marshal.AllocHGlobal((int)structSize);

                    try
                    {
                        Marshal.StructureToPtr(data, ptr, false);
                        DeviceIoControl(handle, FSCTL_SET_ZERO_DATA, ptr,
                                        structSize, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero);
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(ptr);
                    }
                }
            }
            catch (DllNotFoundException)
            {
                SupportsSparse = false;
            }
            catch (EntryPointNotFoundException)
            {
                SupportsSparse = false;
            }
            catch
            {
                // Ignore for now. Maybe if i keep hitting this i should abort future attemts
            }
        }
예제 #2
0
 private static extern Boolean DeviceIoControl(
     IntPtr hDevice,
     UInt32 dwIoControlCode,
     ref FILE_ZERO_DATA_INFORMATION lpInBuffer,
     UInt32 nInBufferSize,
     IntPtr lpOutBuffer,
     UInt32 nOutBufferSize,
     out UInt32 lpBytesReturned,
     IntPtr Overlapped);
        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364597(v=vs.85).aspx"/></summary>
        public void FileSystemSetZeroData(long fileOffset, long length)
        {
            FILE_ZERO_DATA_INFORMATION input = new FILE_ZERO_DATA_INFORMATION();

            input.FileOffset      = fileOffset;
            input.BeyondFinalZero = fileOffset + length;

            DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.FsctlSetZeroData, input);
        }
예제 #4
0
 private static extern bool ZeroFileDeviceIoControl(
     SafeFileHandle handle,
     uint ioControlCode,
     [In] ref FILE_ZERO_DATA_INFORMATION fzdi,
     uint inBufferSize,
     IntPtr pv1,
     uint outBufferSize,
     out uint bytesReturned,
     IntPtr pv2);
        public static void CreateSparse(string filename, long length)
        {
            if (!SupportsSparse)
            {
                return;
            }

            // Ensure we have the full path
            filename = Path.GetFullPath(filename);
            try {
                if (!CanCreateSparse(filename))
                {
                    return;
                }

                // Create a file with the sparse flag enabled

                uint bytesReturned = 0;
                uint access        = 0x40000000;  // GenericWrite
                uint sharing       = 0;           // none
                uint attributes    = 0x00000080;  // Normal
                uint creation      = 1;           // Only create if new

                using SafeFileHandle handle = CreateFileW(filename, access, sharing, IntPtr.Zero, creation, attributes, IntPtr.Zero);
                // If we couldn't create the file, bail out
                if (handle.IsInvalid)
                {
                    return;
                }

                // If we can't set the sparse bit, bail out
                if (!DeviceIoControl(handle, FSCTL_SET_SPARSE, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero))
                {
                    return;
                }

                // Tell the filesystem to mark bytes 0 -> length as sparse zeros
                var    data       = new FILE_ZERO_DATA_INFORMATION(0, length);
                uint   structSize = (uint)Marshal.SizeOf(data);
                IntPtr ptr        = Marshal.AllocHGlobal((int)structSize);

                try {
                    Marshal.StructureToPtr(data, ptr, false);
                    DeviceIoControl(handle, FSCTL_SET_ZERO_DATA, ptr,
                                    structSize, IntPtr.Zero, 0, ref bytesReturned, IntPtr.Zero);
                } finally {
                    Marshal.FreeHGlobal(ptr);
                }
            } catch (DllNotFoundException) {
                SupportsSparse = false;
            } catch (EntryPointNotFoundException) {
                SupportsSparse = false;
            } catch {
                // Ignore for now. Maybe if i keep hitting this i should abort future attemts
            }
        }
예제 #6
0
        internal static unsafe void ZeroFile(SafeFileHandle handle, ulong uptoOffset)
        {
            uint temp;
            FILE_ZERO_DATA_INFORMATION fzdi = new FILE_ZERO_DATA_INFORMATION(0, (long)uptoOffset);
            bool success = ZeroFileDeviceIoControl(handle, FSCTL_SET_ZERO_DATA, ref fzdi, (uint)sizeof(FILE_ZERO_DATA_INFORMATION), IntPtr.Zero, 0, out temp, IntPtr.Zero);

            if (success == false)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            return;
        }
예제 #7
0
    public async Task DeviceIOControlAsync_Overlapped_Works()
    {
        const uint FSCTL_SET_ZERO_DATA = 0x000980c8;
        string     fileName            = Path.GetTempFileName();

        try
        {
            using (var file = CreateFile(
                       filename: fileName,
                       access: Kernel32.ACCESS_MASK.GenericRight.GENERIC_READ | ACCESS_MASK.GenericRight.GENERIC_WRITE,
                       share: Kernel32.FileShare.FILE_SHARE_READ | Kernel32.FileShare.FILE_SHARE_WRITE,
                       securityAttributes: IntPtr.Zero,
                       creationDisposition: CreationDisposition.CREATE_ALWAYS,
                       flagsAndAttributes: CreateFileFlags.FILE_FLAG_OVERLAPPED,
                       SafeObjectHandle.Null))
            {
                Assert.False(file.IsInvalid);

                Assert.True(ThreadPool.BindHandle(file));

                var data = new FILE_ZERO_DATA_INFORMATION[]
                {
                    new FILE_ZERO_DATA_INFORMATION {
                        BeyondFinalZero = int.MaxValue
                    },
                };

                uint ret = await Kernel32.DeviceIoControlAsync <FILE_ZERO_DATA_INFORMATION, byte>(
                    file,
                    (int)FSCTL_SET_ZERO_DATA,
                    data,
                    null,
                    CancellationToken.None);

                Assert.Equal(0u, ret);
            }
        }
        finally
        {
            File.Delete(fileName);
        }
    }