Read File from my Computer using C#

MiPakTeh 1,476 Reputation points
2021-02-07T09:27:10.343+00:00

Hi All,
First I want ask where to select the Language proggraming like C#.

Actually I want to ask how to read all files from my computer using language C#.
Here what I test.

using System;  
using System.IO;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;  
using System.Windows.Forms;  
using Shell32;  



namespace LearningC  
{  
    public partial class Form1 : Form  
    {  
        public Form1()  
        {  
            InitializeComponent();  
        }  

        private void Form1_Load(object sender, EventArgs e)  
        {  

            button1.Text = "Browse Files";  
        }  

        private void button1_Click(object sender, EventArgs e)  
        {  
            listBox1.Items.Clear();  

            string Folder = @"C:\";  
            string[] AllFiles = Directory.GetFiles(Folder, "*.*",SearchOption.AllDirectories);  

            foreach (var A in AllFiles)  
            {  
                listBox1.Items.Add(Path.GetFileName(A));  
            }  


        }  
    }  
}  

I get when the code the files form Recycle bin folder.

System.UnauthorizedAccessException
HResult=0x80070005
Message=Access to the path 'C:\$Recycle.Bin\S-1-5-18' is denied.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileSystemEnumerableIterator1.AddSearchableDirsToStack(SearchData localSearchData) at System.IO.FileSystemEnumerableIterator1.MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.IO.Directory.GetFiles(String path, String searchPattern, SearchOption searchOption)
at LearningC.Form1.button1_Click(Object sender, EventArgs e) in C:\Users\suhai\source\repos\LearningC\LearningC\Form1.cs:line 35
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at LearningC.Program.Main() in C:\Users\suhai\source\repos\LearningC\LearningC\Program.cs:line 19

This exception was originally thrown at this call stack:
[External Code]
LearningC.Form1.button1_Click(object, System.EventArgs) in Form1.cs
[External Code]
LearningC.Program.Main() in Program.cs

Developer technologies C#
{count} votes

Accepted answer
  1. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2021-02-07T15:29:50.68+00:00

    The issues is permissions, not code per-say. You could handle it as follows where on error continue with a recursive process

    using System.Collections.Generic;  
    using System.IO;  
    using System.Linq;  
      
    namespace **Your namespace**  
    {  
        public class DirectoryOperations  
        {  
            public static List<string> GetAllAccessibleDirectories(string path, string searchPattern)  
            {  
                var dirPathList = new List<string>();  
                try  
                {  
                    var childDirPathList = Directory.GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly).ToList();  
                    if (childDirPathList.Count <= 0)  
                    {  
                        return null;  
                    }  
      
                    foreach (var childDirPath in childDirPathList)  
                    {  
                        dirPathList.Add(childDirPath);  
                        List<string> grandChildDirPath = GetAllAccessibleDirectories(childDirPath, searchPattern);  
                          
                        if (grandChildDirPath != null && grandChildDirPath.Count > 0)   
                        {  
                            dirPathList.AddRange(grandChildDirPath.ToArray());  
                        }  
                    }  
                    return dirPathList;   
                }  
                catch  
                {  
                    return null;  
                }  
            }  
        }  
    }  
    

    Usage

    DirectoryOperations.GetAllAccessibleDirectories(@"C:\", "*");  
    

    Or be specific with the exception type of UnauthorizedAccessException

    public static IEnumerable<string> GetAllFiles(string path, string searchPattern)  
    {  
        return Directory.EnumerateFiles(path, searchPattern).Union(  
            Directory.EnumerateDirectories(path).SelectMany(d =>  
            {  
                try  
                {  
                    return GetAllFiles(d, searchPattern);  
                }  
                catch (UnauthorizedAccessException e)  
                {  
                    return Enumerable.Empty<String>();  
                }  
            }));  
    }  
    

    Or even better yet an advance solution the following

    • Is asynchronous which means the UI remains responsive.
    • Provides events to track the operations which is especially useful for large directory structures.
    • Checks for specific errors like UnauthorizedAccessException
    • Attempts to figure out which folders to skip reading
       using System;  
       using System.Collections;  
       using System.Collections.Generic;  
       using System.Diagnostics;  
       using System.Linq;  
       using System.Threading.Tasks;  
       using System.Xml.Linq;  
      
       using System.IO;  
       using System.Threading;  
      
       namespace FileHelpers  
       {  
        public class Operations  
        {  
        public delegate void OnException(Exception exception);  
        public static event OnException OnExceptionEvent;  
        public delegate void OnUnauthorizedAccessException(string message);  
        public static event OnUnauthorizedAccessException UnauthorizedAccessExceptionEvent;  
        public delegate void OnTraverseFolder(string status);  
        public static event OnTraverseFolder OnTraverseEvent;  
        public delegate void OnTraverseExcludeFolder(string sender);  
        public static event OnTraverseExcludeFolder OnTraverseExcludeFolderEvent;  
        public static bool Cancelled = false;  
      
      
        public static async Task RecursiveFolders(DirectoryInfo directoryInfo, string[] excludeFileExtensions, CancellationToken ct)  
        {  
      
        if (!directoryInfo.Exists)  
        {  
        if (OnTraverseEvent != null)  
        OnTraverseEvent("Nothing to process");  
        return;  
        }  
      
        if (!excludeFileExtensions.Any(directoryInfo.FullName.Contains))  
        {  
        await Task.Delay(1);  
        if (OnTraverseEvent != null)  
        OnTraverseEvent(directoryInfo.FullName);  
      
        }  
        else  
        {  
        if (OnTraverseExcludeFolderEvent != null)  
        OnTraverseExcludeFolderEvent(directoryInfo.FullName);  
        }  
      
        DirectoryInfo folder = null;  
      
        try  
        {  
        await Task.Run(async () =>  
        {  
           foreach (DirectoryInfo dir in directoryInfo.EnumerateDirectories())  
           {  
      
           folder = dir;  
      
           if ((folder.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden || (folder.Attributes & FileAttributes.System) == FileAttributes.System || (folder.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)  
           {  
      
           if (OnTraverseExcludeFolderEvent != null)  
           OnTraverseExcludeFolderEvent($"* {folder.FullName}");  
      
           continue;  
      
           }  
      
           if (!Cancelled)  
           {  
      
           await Task.Delay(1);  
           await RecursiveFolders(folder, excludeFileExtensions, ct);  
      
           }  
           else  
           {  
           return;  
           }  
      
           if (ct.IsCancellationRequested)  
           {  
           ct.ThrowIfCancellationRequested();  
           }  
      
           }  
        });  
      
        }  
        catch (Exception ex)  
        {  
        if (ex is OperationCanceledException)  
        {  
        Cancelled = true;  
        }  
        else if (ex is UnauthorizedAccessException)  
        {  
      
        if (UnauthorizedAccessExceptionEvent != null)  
        UnauthorizedAccessExceptionEvent($"Access denied '{ex.Message}'");  
      
        }  
        else  
        {  
      
        if (OnExceptionEvent != null)  
        OnExceptionEvent(ex);  
      
        }  
        }  
        }  
      
        public static void RecursiveFolders(string path, int indentLevel)  
        {  
      
        try  
        {  
      
        if ((File.GetAttributes(path) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)  
        {  
      
        foreach (string folder in Directory.GetDirectories(path))  
        {  
        Debug.WriteLine($"{new string(' ', indentLevel)}{System.IO.Path.GetFileName(folder)}");  
        RecursiveFolders(folder, indentLevel + 2);  
        }  
      
        }  
      
        }  
        catch (UnauthorizedAccessException unauthorized)  
        {  
        Debug.WriteLine($"{unauthorized.Message}");  
        }  
        }  
      
        }  
      
       }  
      

    Edit

    The following code can be viewed online or downloaded (if familiar with Git) using the following script. To keep things simple I show progress in a label but you can also use any control you want.

    mkdir code  
    cd code  
    git init  
    git remote add -f origin https://github.com/karenpayneoregon/csharp-features  
    git sparse-checkout init --cone  
    git sparse-checkout add FileHelpers  
    git sparse-checkout add FileHelpersFrontEnd  
    git pull origin master  
    :clean-up  
    del .gitattributes  
    del .gitignore  
    del .yml  
    del .editorconfig  
    del *.md  
    del *.sln  
    

    Backend class project

    https://github.com/karenpayneoregon/csharp-features/tree/master/FileHelpers

    Frontend form code

    Change the path and exclude extensions to match your needs

    using System;  
    using System.IO;  
    using System.Threading;  
    using System.Windows.Forms;  
    using FileHelpers;  
      
    namespace FileHelpersFrontEnd  
    {  
        public partial class Form1 : Form  
        {  
              
            private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();  
              
            public Form1()  
            {  
                InitializeComponent();  
                  
                Operations.OnTraverseEvent += OperationsOnOnTraverseEvent;  
            }  
      
            private void OperationsOnOnTraverseEvent(string status)  
            {  
                ResultsLabel.InvokeIfRequired(label =>  
                {  
                    label.Text = status;  
                    label.Refresh();  
                });  
            }  
      
            private async void RunButton_Click(object sender, EventArgs e)  
            {  
                if (_cancellationTokenSource.IsCancellationRequested)  
                {  
                    _cancellationTokenSource.Dispose();  
                    _cancellationTokenSource = new CancellationTokenSource();  
                }  
      
                var directoryInfo = new DirectoryInfo("C:\\OED\\Dotnetland\\VS2019\\csharp-tips");  
                  
                try  
                {  
                    await Operations.RecursiveFolders(  
                        directoryInfo,   
                        new[] { "*.txt" },   
                        _cancellationTokenSource.Token);  
                      
                    if (Operations.Cancelled)  
                    {  
                        MessageBox.Show(@"You cancelled the operation");  
                    }  
                    else  
                    {  
                        MessageBox.Show(@"Done");  
                    }  
                }  
                catch (Exception ex)  
                {  
                    MessageBox.Show(ex.Message);  
                }  
            }  
      
            private void CancelButton_Click(object sender, EventArgs e)  
            {  
                _cancellationTokenSource.Cancel();  
            }  
        }  
    }  
    

    67396-11111111111.png

    To prevent cross threading issues use the following extension.

    Frontend project source.


2 additional answers

Sort by: Most helpful
  1. MiPakTeh 1,476 Reputation points
    2021-02-09T04:56:52.163+00:00

    Karen, Thank you very much.

    When run this code it ok but waiting time show all files.

    It possible if I want to see files during in progress .I test loop method
    in click_button.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.IO;
    
    namespace LearningC_1
    {
    
        public partial class Form1 : Form
        {
            public class DirectoryOperations
            {
                public static List<string> GetAllAccessibleDirectories(string path, string searchPattern)
                {
                    var dirPathList = new List<string>();
                    try
                    {
                        var childDirPathList = Directory.GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly).ToList();
                        if (childDirPathList.Count <= 0)
                        {
                            return null;
                        }
    
                        foreach (var childDirPath in childDirPathList)
                        {
                            dirPathList.Add(childDirPath);
                            List<string> grandChildDirPath = GetAllAccessibleDirectories(childDirPath, searchPattern);
    
                            if (grandChildDirPath != null && grandChildDirPath.Count > 0)
                            {
                                dirPathList.AddRange(grandChildDirPath.ToArray());
                            }
                        }
                        return dirPathList;
                    }
                    catch
                    {
                        return null;
                    }
                }
            }
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                button1.Text = "Browse Files";
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                listBox1.Items.Clear();
                var A = DirectoryOperations.GetAllAccessibleDirectories(@"C:\", "*");
    
                for (int i = 0; i < A.Count(); i++)
                {
                    listBox1.Items.Add(Path.GetFileName(A[i].ToString()));
    
                }
            }
        }
    }
    

  2. Castorix31 90,681 Reputation points
    2021-02-09T06:22:04.59+00:00

    A method with NtQueryDirectoryFile which is fast, but slower than reading MFT =>

    (Change the path in BackgroundThread and add a Button for the ckick and a Listbox listBox1)

    Add using System.Runtime.InteropServices; at beginning

    public partial class Form1 : Form
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct UNICODE_STRING
        {
            public ushort Length;
            public ushort MaximumLength;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string Buffer;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        public struct OBJECT_ATTRIBUTES
        {
            public uint Length;
            public IntPtr RootDirectory;
            // Public ObjectName As UNICODE_STRING
            public IntPtr ObjectName;
            public uint Attributes;
            public IntPtr SecurityDescriptor;
            public IntPtr SecurityQualityOfService;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        public struct IO_STATUS_BLOCK
        {
            public uint status;
            public IntPtr information;
        }
    
        public const int FILE_LIST_DIRECTORY = 0x1;
        public const int SYNCHRONIZE = 0x100000;
    
        public const int FILE_SHARE_READ = 1;
        public const int FILE_SHARE_WRITE = 2;
        public const int FILE_SHARE_DELETE = 4;
        public const int FILE_ATTRIBUTE_NORMAL = 0x80;
        public const int FILE_ATTRIBUTE_DIRECTORY = 0x10;
        public const int FILE_ATTRIBUTE_REPARSE_POINT = 0x400;
    
        public const int FILE_DIRECTORY_FILE = 0x1;
        public const int FILE_SYNCHRONOUS_IO_NONALERT = 0x20;
        public const int FILE_OPEN_FOR_BACKUP_INTENT = 0x4000;
    
        public const int OBJ_CASE_INSENSITIVE = 0x40;
    
        public enum FILE_INFORMATION_CLASS
        {
            FileDirectoryInformation = 1,
            FileFullDirectoryInformation,   // 2
            FileBothDirectoryInformation,   // 3
            FileBasicInformation,           // 4  wdm
            FileStandardInformation,        // 5  wdm
            FileInternalInformation,        // 6
            FileEaInformation,              // 7    ,
            FileAccessInformation,          // 8
            FileNameInformation,            // 9
            FileRenameInformation,          // 10
            FileLinkInformation,            // 11
            FileNamesInformation,           // 12
            FileDispositionInformation,     // 13
            FilePositionInformation,        // 14 wdm
            FileFullEaInformation,          // 15
            FileModeInformation,            // 16
            FileAlignmentInformation,       // 17
            FileAllInformation,             // 18
            FileAllocationInformation,      // 19
            FileEndOfFileInformation,       // 20 wdm
            FileAlternateNameInformation,   // 21
            FileStreamInformation,          // 22
            FilePipeInformation,            // 23
            FilePipeLocalInformation,       // 24
            FilePipeRemoteInformation,      // 25
            FileMailslotQueryInformation,   // 26
            FileMailslotSetInformation,     // 27
            FileCompressionInformation,     // 28
            FileObjectIdInformation,        // 29
            FileCompletionInformation,      // 30
            FileMoveClusterInformation,     // 31
            FileQuotaInformation,           // 32
            FileReparsePointInformation,    // 33
            FileNetworkOpenInformation,     // 34
            FileAttributeTagInformation,    // 35
            FileTrackingInformation,        // 36
            FileIdBothDirectoryInformation, // 37
            FileIdFullDirectoryInformation, // 38
            FileValidDataLengthInformation, // 39
            FileShortNameInformation,      // 40
            FileMaximumInformation
        }
    
        [StructLayout(LayoutKind.Explicit)]
        public struct LARGE_INTEGER
        {
            [FieldOffset(0)]
            public uint LowPart;
            [FieldOffset(4)]
            public uint HighPart;
            [FieldOffset(0)]
            public long QuadPart;
        }
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct FILE_BOTH_DIR_INFORMATION
        {
            public uint NextEntryOffset;
            public uint FileIndex;
            public LARGE_INTEGER CreationTime;
            public LARGE_INTEGER LastAccessTime;
            public LARGE_INTEGER LastWriteTime;
            public LARGE_INTEGER ChangeTime;
            public LARGE_INTEGER EndOfFile;
            public LARGE_INTEGER AllocationSize;
            public uint FileAttributes;
            public uint FileNameLength;
            public uint EaSize;
            public char ShortNameLength;
             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
            public string ShortName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string FileName;
        }
    
        public const int STATUS_NO_MORE_FILES = unchecked((int)0x80000006);
    
        [DllImport("NtDll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int NtOpenFile(ref IntPtr FileHandle, int DesiredAccess, ref OBJECT_ATTRIBUTES ObjectAttributes, ref IO_STATUS_BLOCK IoStatusBlock, uint ShareAccess, uint OpenOptions);
    
        //[DllImport("NtDll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        //public static extern int NtQueryDirectoryFile(IntPtr FileHandle, IntPtr pEvent, IntPtr ApcRoutine, IntPtr ApcContext, ref IO_STATUS_BLOCK IoStatusBlock, IntPtr FileInformation, int Length, FILE_INFORMATION_CLASS FileInformationClass, bool ReturnSingleEntry, ref UNICODE_STRING FileName, bool RestartScan);
    
        [DllImport("NtDll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int NtQueryDirectoryFile(IntPtr FileHandle, IntPtr pEvent, IntPtr ApcRoutine, IntPtr ApcContext, ref IO_STATUS_BLOCK IoStatusBlock, IntPtr FileInformation, int Length, FILE_INFORMATION_CLASS FileInformationClass, bool ReturnSingleEntry, IntPtr FileName, bool RestartScan);
    
        [DllImport("NtDll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int NtQueryInformationFile(IntPtr FileHandle, ref IO_STATUS_BLOCK IoStatusBlock, IntPtr FileInformation, int Length, FILE_INFORMATION_CLASS FileInformationClass);
    
        [DllImport("NtDll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern int NtClose(IntPtr handle);
    
        [DllImport("NtDll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern void RtlInitUnicodeString(ref UNICODE_STRING DestinationString, IntPtr SourceString);
    
        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern bool IsWow64Process(IntPtr hProcess, out bool Wow64Process);
    
        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern bool Wow64DisableWow64FsRedirection(out IntPtr OldValue);
    
        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern bool Wow64RevertWow64FsRedirection(IntPtr OldValue);
    
        private OBJECT_ATTRIBUTES InitializeObjectAttributes(UNICODE_STRING objectName, UInt32 Attributes)
        {
            OBJECT_ATTRIBUTES objectAttributes = new OBJECT_ATTRIBUTES();
            objectAttributes.RootDirectory = IntPtr.Zero;
            // objectAttributes.ObjectName = objectName
            objectAttributes.ObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(objectName));
            Marshal.StructureToPtr(objectName, objectAttributes.ObjectName, false);
            objectAttributes.SecurityDescriptor = IntPtr.Zero;
            objectAttributes.SecurityQualityOfService = IntPtr.Zero;
            objectAttributes.Attributes = Attributes;
            objectAttributes.Length = System.Convert.ToUInt32(Marshal.SizeOf(objectAttributes));
            return objectAttributes;
        }
    
        public int nNbFiles = 0;
        public ulong nNbFilesSearch = 0;
        public ulong nTotalSize = 0;
    
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
    
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            nNbFiles = 0;
            nTotalSize = 0;
            System.Threading.Thread btd = new System.Threading.Thread(BackgroundThread);
            btd.IsBackground = true;
            btd.Name = "Background Thread";
            btd.Start();  
        }
    
        public void BackgroundThread()
        {
            bool bWow64 = false;
            IntPtr OldValue = IntPtr.Zero;
            IsWow64Process(System.Diagnostics.Process.GetCurrentProcess().Handle, out bWow64);
            if (bWow64)
            {               
                bool bRet = Wow64DisableWow64FsRedirection(out OldValue);
            }
    
            // ScanDirectory(@"e:\");
            // ScanDirectory(@"e:\test2");
            // ScanDirectory(@"e:\games");
            ScanDirectory(@"c:\windows\system32");
            // ScanDirectory(@"c:\windows");
    
            if ((bWow64))
                Wow64RevertWow64FsRedirection(OldValue);
            MessageBox.Show(string.Format("Nb files : {0}{1}Size : {2}", nNbFiles, Environment.NewLine, nTotalSize), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    
        private void ScanDirectory(string sDirectory)
        {
            UNICODE_STRING RootDirectoryName = new UNICODE_STRING();
            string sPath = sDirectory;
            string sBuffer = string.Format(@"\??\{0}\", sPath);
            IntPtr pBuffer = Marshal.StringToHGlobalUni(sBuffer);
            RtlInitUnicodeString(ref RootDirectoryName, pBuffer);
            OBJECT_ATTRIBUTES RootDirectoryAttributes = new OBJECT_ATTRIBUTES();
            RootDirectoryAttributes = InitializeObjectAttributes(RootDirectoryName, OBJ_CASE_INSENSITIVE);
    
            IO_STATUS_BLOCK IoStatusBlock = new IO_STATUS_BLOCK();
            IntPtr hFile = IntPtr.Zero;
            // 0xC000000D STATUS_INVALID_PARAMETER 
            int NtStatus = NtOpenFile(ref hFile, FILE_LIST_DIRECTORY | SYNCHRONIZE, ref RootDirectoryAttributes, ref IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT);
            Marshal.FreeHGlobal(RootDirectoryAttributes.ObjectName);
            if (NtStatus == 0)
            {
                FILE_BOTH_DIR_INFORMATION DirectoryInfo = new FILE_BOTH_DIR_INFORMATION();
                // Dim nBufferSize As Integer = (2 * 260) + Marshal.SizeOf(DirectoryInfo)
                int nBufferSize = Marshal.SizeOf(DirectoryInfo);
                IntPtr pDirectoryInfo = IntPtr.Zero;
                pDirectoryInfo = Marshal.AllocHGlobal(nBufferSize);
                Marshal.StructureToPtr(DirectoryInfo, pDirectoryInfo, false);
                int nSize = Marshal.SizeOf(DirectoryInfo);
                FILE_BOTH_DIR_INFORMATION pDirectoryInfoRet = new FILE_BOTH_DIR_INFORMATION();
                bool b = true;
                while (true)
                {
                    NtStatus = NtQueryDirectoryFile(hFile, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref IoStatusBlock, pDirectoryInfo, nBufferSize, FILE_INFORMATION_CLASS.FileBothDirectoryInformation, true, IntPtr.Zero, b);
                    if (NtStatus == STATUS_NO_MORE_FILES)
                    {
                        NtStatus = 0;
                        break;
                    }
                    if (NtStatus != 0)
                        break;
                    pDirectoryInfoRet = (FILE_BOTH_DIR_INFORMATION)Marshal.PtrToStructure(pDirectoryInfo, typeof(FILE_BOTH_DIR_INFORMATION));
                    b = false;
                    string sFileName = pDirectoryInfoRet.FileName.Substring(0, System.Convert.ToInt32(pDirectoryInfoRet.FileNameLength / (double)2));
    
                    if ((pDirectoryInfoRet.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
                    {
                        // If sFileName.Contains("rld-gtav.iso") Then
                        // nNbFilesSearch = nNbFilesSearch
                        // End If
    
                        // Console.WriteLine("File: {0}", sFileName)
                        // If sFileName.Contains(".avi") Then
                        // nNbFilesSearch += 1
                        // End If
                        nNbFiles += 1;
    
                        listBox1.Invoke((Action)(() => listBox1.Items.Add(sPath + "\\" + sFileName)));
    
                        nTotalSize += (System.Convert.ToUInt64(pDirectoryInfoRet.EndOfFile.HighPart) << 32) + pDirectoryInfoRet.EndOfFile.LowPart;
                    }
                    else
                    {
                    }
                    if ((pDirectoryInfoRet.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY & string.Compare(sFileName, ".") != 0 & string.Compare(sFileName, "..") != 0 & (pDirectoryInfoRet.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != FILE_ATTRIBUTE_REPARSE_POINT)
                    {
                        string sTempPath = string.Format(@"{0}\{1}", sPath, sFileName);
                        ScanDirectory(sTempPath);
                    }
                }
                Marshal.FreeHGlobal(pDirectoryInfo);
                NtClose(hFile);
            }
        }
    }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.