Ejemplo n.º 1
0
        public unsafe MFT_FILE_INFO[] read(DriveInfo driveInfo)
        {
            TimeSpan utcOffset = System.TimeZoneInfo.Local.BaseUtcOffset;
            var      baseticks = (ulong)(new DateTime(1601, 01, 01).Ticks + utcOffset.Ticks);

            string pathRoot = string.Concat(@"\\.\", driveInfo.Name.Substring(0, 2));

            var hVolume = Win32API.CreateFile(
                pathRoot,
                Win32API.GENERIC_READ | Win32API.GENERIC_WRITE,
                Win32API.FILE_SHARE_READ | Win32API.FILE_SHARE_WRITE,
                IntPtr.Zero,
                Win32API.OPEN_EXISTING,
                0,
                IntPtr.Zero);

            if (hVolume.ToInt32() == Win32API.INVALID_HANDLE_VALUE)
            {
                Win32API.CloseHandle(hVolume);
                //Marshal.GetLastWin32Error
                return(new MFT_FILE_INFO[1]);
            }

            Win32API.NTFS_VOLUME_DATA_BUFFER ntfsVolData = new Win32API.NTFS_VOLUME_DATA_BUFFER();
            int    ntfsVolDataSize = Marshal.SizeOf(ntfsVolData);
            IntPtr volBuffer       = Marshal.AllocHGlobal(ntfsVolDataSize);
            //Win32API.ZeroMemory(volBuffer, ntfsVolDataSize);
            //Marshal.StructureToPtr(ntfsVolData, volBuffer, true);

            uint lpBytesReturned = 0;
            var  ret             = Win32API.DeviceIoControl(
                hVolume,
                Win32API.FSCTL_GET_NTFS_VOLUME_DATA,
                IntPtr.Zero,
                0,
                volBuffer,
                ntfsVolDataSize,
                out lpBytesReturned,
                IntPtr.Zero);

            ntfsVolData = (Win32API.NTFS_VOLUME_DATA_BUFFER)Marshal.PtrToStructure(volBuffer, typeof(Win32API.NTFS_VOLUME_DATA_BUFFER));
            Marshal.FreeHGlobal(volBuffer);

            if (ret)
            {
                //Console.WriteLine("Volume Serial Number: 0X%.8X%.8X\n", ntfsVolData.VolumeSerialNumber.HighPart, ntfsVolData.VolumeSerialNumber.LowPart);
                Console.WriteLine("The number of bytes in a cluster: {0}", ntfsVolData.BytesPerCluster);
                Console.WriteLine("The number of bytes in a file record segment: {0}", ntfsVolData.BytesPerFileRecordSegment);
                Console.WriteLine("The number of bytes in a sector: {0}", ntfsVolData.BytesPerSector);
                Console.WriteLine("The number of clusters in a file record segment: {0}", ntfsVolData.ClustersPerFileRecordSegment);
                Console.WriteLine("The number of free clusters in the specified volume: {0}", ntfsVolData.FreeClusters);
                //Console.WriteLine("The starting logical cluster number of the master file table mirror: 0X%.8X%.8X\n", ntfsVolData.Mft2StartLcn.HighPart, ntfsVolData.Mft2StartLcn.LowPart);
                //Console.WriteLine("The starting logical cluster number of the master file table: 0X%.8X%.8X\n", ntfsVolData.MftStartLcn.HighPart, ntfsVolData.MftStartLcn.LowPart);
                Console.WriteLine("The length of the master file table, in bytes: {0}", ntfsVolData.MftValidDataLength);
                //Console.WriteLine("The ending logical cluster number of the master file table zone: 0X%.8X%.8X\n", ntfsVolData.MftZoneEnd.HighPart, ntfsVolData.MftZoneEnd.LowPart);
                //Console.WriteLine("The starting logical cluster number of the master file table zone: 0X%.8X%.8X\n", ntfsVolData.MftZoneStart.HighPart, ntfsVolData.MftZoneStart.LowPart);
                Console.WriteLine("The number of sectors: {0}", ntfsVolData.NumberSectors);
                Console.WriteLine("Total Clusters (used and free): {0}", ntfsVolData.TotalClusters);
                Console.WriteLine("The number of reserved clusters: {0}\n", ntfsVolData.TotalReserved);
            }

            Int64 QuadPart         = 1024; // 1024 or 2048
            long  total_file_count = (ntfsVolData.MftValidDataLength / QuadPart);

            //total_file_count = total_file_count / 1000; //test
            //Int32[] parentid = new Int32[total_file_count];
            MFT_FILE_INFO[] fileinfos = new MFT_FILE_INFO[total_file_count];

            Win32API.NTFS_FILE_RECORD_OUTPUT_BUFFER ob = new Win32API.NTFS_FILE_RECORD_OUTPUT_BUFFER();
            int obSize = Marshal.SizeOf(ob) + ntfsVolData.BytesPerFileRecordSegment - 1;

            //int obSize = sizeof(Win32API.NTFS_FILE_RECORD_OUTPUT_BUFFER) + ntfsVolData.BytesPerFileRecordSegment - 1;

            Win32API.NTFS_FILE_RECORD_INPUT_BUFFER mftRecordInput = new Win32API.NTFS_FILE_RECORD_INPUT_BUFFER();
            int mftRecordInputSize = Marshal.SizeOf(mftRecordInput);

            bool abort = false;
            int  per   = 0;
            //Win32API.FILE_RECORD_HEADER hdum = new Win32API.FILE_RECORD_HEADER();
            //int hdumSize = Marshal.SizeOf(hdum);
            long start = 0;

            for (long i = start; i < total_file_count; i++)
            {
                mftRecordInput.FileReferenceNumber = i;

                IntPtr input_buffer = Marshal.AllocHGlobal(mftRecordInputSize);
                Win32API.ZeroMemory(input_buffer, mftRecordInputSize);
                Marshal.StructureToPtr(mftRecordInput, input_buffer, true);

                IntPtr output_buffer = Marshal.AllocHGlobal(obSize);

                if (i == total_file_count * 0.2)
                {
                    s20 = DateTime.Now;
                }
                else if (i == total_file_count * 0.5)
                {
                    s50 = DateTime.Now;
                }
                else if (i == total_file_count * 0.9)
                {
                    s90 = DateTime.Now;
                }

                var bDioControl = Win32API.DeviceIoControl(
                    hVolume,
                    Win32API.FSCTL_GET_NTFS_FILE_RECORD,
                    input_buffer,
                    mftRecordInputSize,
                    output_buffer,
                    obSize,
                    out lpBytesReturned,
                    IntPtr.Zero);


                //IntPtr hp = Marshal.AllocHGlobal(hdumSize);
                //uint read = 0;
                //Marshal.StructureToPtr(hdum, hp, true);
                //byte[] buffer = new byte[Marshal.SizeOf(hdum)];
                //fixed (byte* p = buffer) {
                //    //ReadFile(readhandle, p, lpNumberOfBytesRead, &n, 0);
                //    Win32API.ReadFile(hVolume, hp, (uint)(1024 * ntfsVolData.BytesPerCluster), ref read, IntPtr.Zero);
                //    Win32API.FILE_RECORD_HEADER* ph = (Win32API.FILE_RECORD_HEADER*)((int)hp);
                //}

                //fixed (Win32API.NTFS_FILE_RECORD_INPUT_BUFFER* ptr = (&mftRecordInput)) {
                //    var bDioControl = Win32API.DeviceIoControl(
                //        hVolume,
                //        Win32API.FSCTL_GET_NTFS_FILE_RECORD,
                //        (IntPtr)ptr,
                //        mftRecordInputSize,
                //        output_buffer,
                //        obSize,
                //        out lpBytesReturned,
                //        IntPtr.Zero);
                //}


                Win32API.FILE_RECORD_HEADER *p_file_record_header;

                var outbuff = Win32API.NTFS_FILE_RECORD_OUTPUT_BUFFER.FromPtr(output_buffer);
                //byte* ptr = (byte*)output_buffer + (int)Marshal.OffsetOf(typeof(Win32API.NTFS_FILE_RECORD_OUTPUT_BUFFER), "FileRecordBuffer");

                fixed(byte *ptr = &outbuff.FileRecordBuffer[0])
                {
                    p_file_record_header = (Win32API.FILE_RECORD_HEADER *)ptr;

                    Win32API.RECORD_ATTRIBUTE *attr = (Win32API.RECORD_ATTRIBUTE *)((int)ptr + p_file_record_header->AttributesOffset);

                    Win32API.STANDARD_INFORMATION *si;
                    if (p_file_record_header->Ntfs.Type == 1162627398)  //'ELIF'
                    {
                        int stop = Math.Min(8, (int)p_file_record_header->NextAttributeNumber);
                        for (int j = 0; j < stop; j++)
                        {
                            //while (true) {
                            if (attr->AttributeType < 0 || (int)attr->AttributeType > 0x100)
                            {
                                break;
                            }

                            switch (attr->AttributeType)
                            {
                            case Win32API.AttributeType.AttributeFileName:
                                //Win32API.RESIDENT_ATTRIBUTE* regsttr = (Win32API.RESIDENT_ATTRIBUTE*)attr;
                                Win32API.FILENAME_ATTRIBUTE fattr =
                                    (Win32API.FILENAME_ATTRIBUTE)Marshal.PtrToStructure((IntPtr)((((byte *)attr) + ((Win32API.RESIDENT_ATTRIBUTE *)attr)->ValueOffset)), typeof(Win32API.FILENAME_ATTRIBUTE));
                                //parentid[i] = (Int32)fattr.DirectoryFileReferenceNumber;
                                fileinfos[i].ParentID    = (Int32)fattr.DirectoryFileReferenceNumber;
                                fileinfos[i].IsDirectory = ((p_file_record_header->Flags & 0x2) == 2);
                                fileinfos[i].Name        = fattr.Name.Substring(0, fattr.NameLength);
                                //if (fattr.NameLength > 3) {
                                //    fileinfos[i].Name = fattr.Name.Substring(0, fattr.NameLength);
                                //}
                                //else {
                                //    fileinfos[i].Name = fattr.Name.Substring(0, fattr.NameLength);
                                //}
                                //fileinfos[i].Name = fattr.Name;
                                //fileinfos[i].Size = fattr.DataSize;
                                //goto BB;
                                break;

                            case Win32API.AttributeType.AttributeStandardInformation:
                                //var off = (Win32API.RESIDENT_ATTRIBUTE*)attr;
                                si = (Win32API.STANDARD_INFORMATION *)((byte *)attr + ((Win32API.RESIDENT_ATTRIBUTE *)attr)->ValueOffset);
                                //Win32API.STANDARD_INFORMATION sattr =
                                //(Win32API.STANDARD_INFORMATION)Marshal.PtrToStructure(new IntPtr(&attr + off->ValueOffset), typeof(Win32API.STANDARD_INFORMATION));
                                //fileinfos[i].CreationTime = si->CreationTime;
                                //fileinfos[i].LastWriteTime = si->LastWriteTime;
                                fileinfos[i].CreationTime  = new DateTime((long)(si->CreationTime + baseticks));
                                fileinfos[i].LastWriteTime = new DateTime((long)(si->LastWriteTime + baseticks));
                                break;

                            case Win32API.AttributeType.AttributeData:
                                if (attr->NonResident == 1)
                                {
                                    fileinfos[i].Size = ((Win32API.NONRESIDENT_ATTRIBUTE *)attr)->DataSize;
                                }
                                else
                                {
                                    fileinfos[i].Size = ((Win32API.RESIDENT_ATTRIBUTE *)attr)->ValueLength;
                                }
                                break;

                            default:
                                break;
                            }

                            if (attr->Length > 0 && attr->Length < (int)p_file_record_header->BytesInUse)
                            {
                                attr = (Win32API.RECORD_ATTRIBUTE *)((byte *)attr + attr->Length);
                            }
                            else
                            if (attr->NonResident == 1)    //TRUE)
                            {
                                attr = (Win32API.RECORD_ATTRIBUTE *)((byte *)attr + sizeof(Win32API.NONRESIDENT_ATTRIBUTE));
                            }
                        }
                        //BB:
                        //    ;
                        //if (fileinfos[i].Name != null && fileinfos[i].Name.Contains("wv.ncb")) {
                        //    var f = fileinfos[i];
                        //    var ss = f.Size;
                        //    int h = 0;
                        //}
                    }
                }

                Marshal.FreeHGlobal(output_buffer);
                Marshal.FreeHGlobal(input_buffer);


                if (i == total_file_count * 0.21)
                {
                    sp20 = DateTime.Now - s20;
                }
                else if (i == total_file_count * 0.51)
                {
                    sp50 = DateTime.Now - s50;
                }
                else if (i == total_file_count * 0.91)
                {
                    sp90 = DateTime.Now - s90;
                }

                if (CallBackEvent != null && (per < i * 100 / total_file_count))
                {
                    per   = (int)(i * 100 / total_file_count);
                    abort = CallBackEvent(per);
                    if (abort)
                    {
                        break;
                    }
                }
            }

            Win32API.CloseHandle(hVolume);

            var di20 = sp20.TotalMilliseconds;
            var di50 = sp50.TotalMilliseconds;
            var di90 = sp90.TotalMilliseconds;

            //{
            //    int start = 27;
            //    StringBuilder buf = new StringBuilder();
            //    var stack = new List<Int32>();
            //    int count = fileinfos.Count();
            //    for (int i = start; i < count; i++) {
            //        if (fileinfos[i].Name != null) {

            //            stack.Clear();
            //            var parent = parentid[i];
            //            while ((parent != 0 && parent != 5) && parent < count) {
            //                stack.Add(parent);
            //                parent = parentid[parent];
            //            }
            //            stack.Reverse();

            //            buf.Remove(0, buf.Length);
            //            buf.Append(driveInfo.Name);
            //            foreach (var item in stack) {
            //                buf.Append(fileinfos[item].Name);
            //                buf.Append(@"\");
            //            }
            //            fileinfos[i].Path = buf.ToString();
            //        }
            //    }
            //}

            return(fileinfos);
        }
Ejemplo n.º 2
0
        public unsafe MFT_FILE_INFO[] read(DriveInfo driveInfo)
        {
            TimeSpan utcOffset = System.TimeZoneInfo.Local.BaseUtcOffset;
            var baseticks = (ulong)(new DateTime(1601, 01, 01).Ticks + utcOffset.Ticks);

            string pathRoot = string.Concat(@"\\.\", driveInfo.Name.Substring(0, 2));

            var hVolume = Win32API.CreateFile(
                pathRoot,
                Win32API.GENERIC_READ | Win32API.GENERIC_WRITE,
                Win32API.FILE_SHARE_READ | Win32API.FILE_SHARE_WRITE,
                IntPtr.Zero,
                Win32API.OPEN_EXISTING,
                0,
                IntPtr.Zero);

            if (hVolume.ToInt32() == Win32API.INVALID_HANDLE_VALUE) {
                Win32API.CloseHandle(hVolume);
                //Marshal.GetLastWin32Error
                return new MFT_FILE_INFO[1];
            }

            Win32API.NTFS_VOLUME_DATA_BUFFER ntfsVolData = new Win32API.NTFS_VOLUME_DATA_BUFFER();
            int ntfsVolDataSize = Marshal.SizeOf(ntfsVolData);
            IntPtr volBuffer = Marshal.AllocHGlobal(ntfsVolDataSize);
            //Win32API.ZeroMemory(volBuffer, ntfsVolDataSize);
            //Marshal.StructureToPtr(ntfsVolData, volBuffer, true);

            uint lpBytesReturned = 0;
            var ret = Win32API.DeviceIoControl(
                hVolume,
                Win32API.FSCTL_GET_NTFS_VOLUME_DATA,
                IntPtr.Zero,
                0,
                volBuffer,
                ntfsVolDataSize,
                out lpBytesReturned,
                IntPtr.Zero);

            ntfsVolData = (Win32API.NTFS_VOLUME_DATA_BUFFER)Marshal.PtrToStructure(volBuffer, typeof(Win32API.NTFS_VOLUME_DATA_BUFFER));
            Marshal.FreeHGlobal(volBuffer);

            if (ret) {

                //Console.WriteLine("Volume Serial Number: 0X%.8X%.8X\n", ntfsVolData.VolumeSerialNumber.HighPart, ntfsVolData.VolumeSerialNumber.LowPart);
                Console.WriteLine("The number of bytes in a cluster: {0}", ntfsVolData.BytesPerCluster);
                Console.WriteLine("The number of bytes in a file record segment: {0}", ntfsVolData.BytesPerFileRecordSegment);
                Console.WriteLine("The number of bytes in a sector: {0}", ntfsVolData.BytesPerSector);
                Console.WriteLine("The number of clusters in a file record segment: {0}", ntfsVolData.ClustersPerFileRecordSegment);
                Console.WriteLine("The number of free clusters in the specified volume: {0}", ntfsVolData.FreeClusters);
                //Console.WriteLine("The starting logical cluster number of the master file table mirror: 0X%.8X%.8X\n", ntfsVolData.Mft2StartLcn.HighPart, ntfsVolData.Mft2StartLcn.LowPart);
                //Console.WriteLine("The starting logical cluster number of the master file table: 0X%.8X%.8X\n", ntfsVolData.MftStartLcn.HighPart, ntfsVolData.MftStartLcn.LowPart);
                Console.WriteLine("The length of the master file table, in bytes: {0}", ntfsVolData.MftValidDataLength);
                //Console.WriteLine("The ending logical cluster number of the master file table zone: 0X%.8X%.8X\n", ntfsVolData.MftZoneEnd.HighPart, ntfsVolData.MftZoneEnd.LowPart);
                //Console.WriteLine("The starting logical cluster number of the master file table zone: 0X%.8X%.8X\n", ntfsVolData.MftZoneStart.HighPart, ntfsVolData.MftZoneStart.LowPart);
                Console.WriteLine("The number of sectors: {0}", ntfsVolData.NumberSectors);
                Console.WriteLine("Total Clusters (used and free): {0}", ntfsVolData.TotalClusters);
                Console.WriteLine("The number of reserved clusters: {0}\n", ntfsVolData.TotalReserved);
            }

            Int64 QuadPart = 1024; // 1024 or 2048
            long total_file_count = (ntfsVolData.MftValidDataLength / QuadPart);

            //total_file_count = total_file_count / 1000; //test
            //Int32[] parentid = new Int32[total_file_count];
            MFT_FILE_INFO[] fileinfos = new MFT_FILE_INFO[total_file_count];

            Win32API.NTFS_FILE_RECORD_OUTPUT_BUFFER ob = new Win32API.NTFS_FILE_RECORD_OUTPUT_BUFFER();
            int obSize = Marshal.SizeOf(ob) + ntfsVolData.BytesPerFileRecordSegment - 1;
            //int obSize = sizeof(Win32API.NTFS_FILE_RECORD_OUTPUT_BUFFER) + ntfsVolData.BytesPerFileRecordSegment - 1;

            Win32API.NTFS_FILE_RECORD_INPUT_BUFFER mftRecordInput = new Win32API.NTFS_FILE_RECORD_INPUT_BUFFER();
            int mftRecordInputSize = Marshal.SizeOf(mftRecordInput);

            bool abort = false;
            int per = 0;
            //Win32API.FILE_RECORD_HEADER hdum = new Win32API.FILE_RECORD_HEADER();
            //int hdumSize = Marshal.SizeOf(hdum);
            long start = 0;
            for (long i = start; i < total_file_count; i++) {

                mftRecordInput.FileReferenceNumber = i;

                IntPtr input_buffer = Marshal.AllocHGlobal(mftRecordInputSize);
                Win32API.ZeroMemory(input_buffer, mftRecordInputSize);
                Marshal.StructureToPtr(mftRecordInput, input_buffer, true);

                IntPtr output_buffer = Marshal.AllocHGlobal(obSize);

                if (i == total_file_count * 0.2)
                    s20 = DateTime.Now;
                else if (i == total_file_count * 0.5)
                    s50 = DateTime.Now;
                else if (i == total_file_count * 0.9)
                    s90 = DateTime.Now;

                var bDioControl = Win32API.DeviceIoControl(
                    hVolume,
                    Win32API.FSCTL_GET_NTFS_FILE_RECORD,
                    input_buffer,
                    mftRecordInputSize,
                    output_buffer,
                    obSize,
                    out lpBytesReturned,
                    IntPtr.Zero);

                //IntPtr hp = Marshal.AllocHGlobal(hdumSize);
                //uint read = 0;
                //Marshal.StructureToPtr(hdum, hp, true);
                //byte[] buffer = new byte[Marshal.SizeOf(hdum)];
                //fixed (byte* p = buffer) {
                //    //ReadFile(readhandle, p, lpNumberOfBytesRead, &n, 0);
                //    Win32API.ReadFile(hVolume, hp, (uint)(1024 * ntfsVolData.BytesPerCluster), ref read, IntPtr.Zero);
                //    Win32API.FILE_RECORD_HEADER* ph = (Win32API.FILE_RECORD_HEADER*)((int)hp);
                //}

                //fixed (Win32API.NTFS_FILE_RECORD_INPUT_BUFFER* ptr = (&mftRecordInput)) {
                //    var bDioControl = Win32API.DeviceIoControl(
                //        hVolume,
                //        Win32API.FSCTL_GET_NTFS_FILE_RECORD,
                //        (IntPtr)ptr,
                //        mftRecordInputSize,
                //        output_buffer,
                //        obSize,
                //        out lpBytesReturned,
                //        IntPtr.Zero);
                //}

                Win32API.FILE_RECORD_HEADER* p_file_record_header;

                var outbuff = Win32API.NTFS_FILE_RECORD_OUTPUT_BUFFER.FromPtr(output_buffer);
                //byte* ptr = (byte*)output_buffer + (int)Marshal.OffsetOf(typeof(Win32API.NTFS_FILE_RECORD_OUTPUT_BUFFER), "FileRecordBuffer");

                fixed (byte* ptr = &outbuff.FileRecordBuffer[0]) {
                    p_file_record_header = (Win32API.FILE_RECORD_HEADER*)ptr;

                    Win32API.RECORD_ATTRIBUTE* attr = (Win32API.RECORD_ATTRIBUTE*)((int)ptr + p_file_record_header->AttributesOffset);

                    Win32API.STANDARD_INFORMATION* si;
                    if (p_file_record_header->Ntfs.Type == 1162627398) {//'ELIF'
                        int stop = Math.Min(8, (int)p_file_record_header->NextAttributeNumber);
                        for (int j=0;j<stop;j++){
                        //while (true) {
                            if (attr->AttributeType < 0 || (int)attr->AttributeType > 0x100) break;

                            switch (attr->AttributeType) {
                                case Win32API.AttributeType.AttributeFileName:
                                    //Win32API.RESIDENT_ATTRIBUTE* regsttr = (Win32API.RESIDENT_ATTRIBUTE*)attr;
                                    Win32API.FILENAME_ATTRIBUTE fattr =
                                        (Win32API.FILENAME_ATTRIBUTE)Marshal.PtrToStructure((IntPtr)((((byte*)attr) + ((Win32API.RESIDENT_ATTRIBUTE*)attr)->ValueOffset)), typeof(Win32API.FILENAME_ATTRIBUTE));
                                    //parentid[i] = (Int32)fattr.DirectoryFileReferenceNumber;
                                    fileinfos[i].ParentID = (Int32)fattr.DirectoryFileReferenceNumber;
                                    fileinfos[i].IsDirectory = ((p_file_record_header->Flags & 0x2) == 2);
                                    fileinfos[i].Name = fattr.Name.Substring(0, fattr.NameLength);
                                    //if (fattr.NameLength > 3) {
                                    //    fileinfos[i].Name = fattr.Name.Substring(0, fattr.NameLength);
                                    //}
                                    //else {
                                    //    fileinfos[i].Name = fattr.Name.Substring(0, fattr.NameLength);
                                    //}
                                    //fileinfos[i].Name = fattr.Name;
                                    //fileinfos[i].Size = fattr.DataSize;
                                    //goto BB;
                                    break;

                                case Win32API.AttributeType.AttributeStandardInformation:
                                    //var off = (Win32API.RESIDENT_ATTRIBUTE*)attr;
                                    si = (Win32API.STANDARD_INFORMATION*)((byte*)attr + ((Win32API.RESIDENT_ATTRIBUTE*)attr)->ValueOffset);
                                    //Win32API.STANDARD_INFORMATION sattr =
                                    //(Win32API.STANDARD_INFORMATION)Marshal.PtrToStructure(new IntPtr(&attr + off->ValueOffset), typeof(Win32API.STANDARD_INFORMATION));
                                    //fileinfos[i].CreationTime = si->CreationTime;
                                    //fileinfos[i].LastWriteTime = si->LastWriteTime;
                                    fileinfos[i].CreationTime = new DateTime((long)(si->CreationTime + baseticks));
                                    fileinfos[i].LastWriteTime =new DateTime((long)(si->LastWriteTime + baseticks));
                                    break;
                                case Win32API.AttributeType.AttributeData:
                                    if (attr->NonResident == 1) {
                                        fileinfos[i].Size = ((Win32API.NONRESIDENT_ATTRIBUTE*)attr)->DataSize;
                                    } else {
                                        fileinfos[i].Size = ((Win32API.RESIDENT_ATTRIBUTE*)attr)->ValueLength;
                                    }
                                    break;
                                default:
                                    break;
                            }

                            if (attr->Length > 0 && attr->Length < (int)p_file_record_header->BytesInUse)
                                attr = (Win32API.RECORD_ATTRIBUTE*)((byte*)attr + attr->Length);
                            else
                                if (attr->NonResident == 1)//TRUE)
                                    attr = (Win32API.RECORD_ATTRIBUTE*)((byte*)attr + sizeof(Win32API.NONRESIDENT_ATTRIBUTE));
                        }
                    //BB:
                    //    ;
                        //if (fileinfos[i].Name != null && fileinfos[i].Name.Contains("wv.ncb")) {
                        //    var f = fileinfos[i];
                        //    var ss = f.Size;
                        //    int h = 0;
                        //}
                    }

                }
                Marshal.FreeHGlobal(output_buffer);
                Marshal.FreeHGlobal(input_buffer);

                if (i == total_file_count * 0.21)
                    sp20 = DateTime.Now - s20;
                else if (i == total_file_count * 0.51)
                    sp50 = DateTime.Now - s50;
                else if (i == total_file_count * 0.91)
                    sp90 = DateTime.Now - s90;

                if (CallBackEvent != null && (per < i * 100 / total_file_count)) {
                    per = (int)(i * 100 / total_file_count);
                    abort = CallBackEvent(per);
                    if (abort) {
                        break;
                    }
                }
            }

            Win32API.CloseHandle(hVolume);

            var di20 = sp20.TotalMilliseconds;
            var di50 = sp50.TotalMilliseconds;
            var di90 = sp90.TotalMilliseconds;

            //{
            //    int start = 27;
            //    StringBuilder buf = new StringBuilder();
            //    var stack = new List<Int32>();
            //    int count = fileinfos.Count();
            //    for (int i = start; i < count; i++) {
            //        if (fileinfos[i].Name != null) {

            //            stack.Clear();
            //            var parent = parentid[i];
            //            while ((parent != 0 && parent != 5) && parent < count) {
            //                stack.Add(parent);
            //                parent = parentid[parent];
            //            }
            //            stack.Reverse();

            //            buf.Remove(0, buf.Length);
            //            buf.Append(driveInfo.Name);
            //            foreach (var item in stack) {
            //                buf.Append(fileinfos[item].Name);
            //                buf.Append(@"\");
            //            }
            //            fileinfos[i].Path = buf.ToString();
            //        }
            //    }
            //}

            return fileinfos;
        }