//FsctlAllowExtendedDasdIo //FsctlCreateOrGetObjectId //FsctlDeleteObjectId //FsctlDeleteReparsePoint //FsctlDismountVolume //FsctlDumpPropertyData //FsctlEnableUpgrade //FsctlEncryptionFsctlIo //FsctlExtendVolume /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364565(v=vs.85).aspx"/></summary> public FileSystemStats[] FileSystemGetStatistics() { byte[] data = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.FsctlFileSystemGetStatistics, 512); FileSystemStats[] res; using (UnmanagedMemory mem = new UnmanagedMemory(data)) { IntPtr currentDataPtr = mem; FILESYSTEM_STATISTICS firstStats = (FILESYSTEM_STATISTICS)Marshal.PtrToStructure(currentDataPtr, typeof(FILESYSTEM_STATISTICS)); int fsStatsSize = Marshal.SizeOf(typeof(FILESYSTEM_STATISTICS)); int elementSize = (int)firstStats.SizeOfCompleteStructure; int procCount = data.Length / elementSize; res = new FileSystemStats[procCount]; for (int i = 0; i < procCount; i++) { res[i] = new FileSystemStats(); res[i].Stats = (FILESYSTEM_STATISTICS)Marshal.PtrToStructure(currentDataPtr, typeof(FILESYSTEM_STATISTICS)); switch (res[i].Stats.FileSystemType) { case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_NTFS: NTFS_STATISTICS ntfsStats = (NTFS_STATISTICS)Marshal.PtrToStructure(currentDataPtr + fsStatsSize, typeof(NTFS_STATISTICS)); res[i].FSStats = ntfsStats; break; case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_FAT: FAT_STATISTICS fatStats = (FAT_STATISTICS)Marshal.PtrToStructure(currentDataPtr + fsStatsSize, typeof(FAT_STATISTICS)); res[i].FSStats = fatStats; break; case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_EXFAT: EXFAT_STATISTICS exFatStats = (EXFAT_STATISTICS)Marshal.PtrToStructure(currentDataPtr + fsStatsSize, typeof(EXFAT_STATISTICS)); res[i].FSStats = exFatStats; break; default: throw new ArgumentOutOfRangeException(); } currentDataPtr += elementSize; } } return(res); }
private static void ExampleFileSystemIO() { const string drive = @"\\.\C:"; Console.WriteLine(@"## Exmaple on {0} ##", drive); SafeFileHandle volumeHandle = CreateFile(drive, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero); if (volumeHandle.IsInvalid) { int lastError = Marshal.GetLastWin32Error(); Console.WriteLine(@"!! Invalid {0}; Error ({1}): {2}", drive, lastError, new Win32Exception(lastError).Message); Console.WriteLine(); return; } using (volumeHandle) { // Extract a complete file list from the target drive IUSN_RECORD[] usnData; using (UsnDeviceWrapper usnIo = new UsnDeviceWrapper(volumeHandle)) usnData = usnIo.FileSystemEnumUsnData(); Console.WriteLine("Found {0:N0} file/folder records", usnData.Length); // Count the unique file names int usnNameUniques = new HashSet <string>(usnData.Select(s => s.FileName)).Count; Console.WriteLine("Found {0:N0} unique names on records", usnNameUniques); // Prepare a dictionary to resolve parents Dictionary <ulong, USN_RECORD_V2> usnDic = usnData.OfType <USN_RECORD_V2>().ToDictionary(s => s.FileReferenceNumber); const string root = drive + "\\"; List <string> files = new List <string>(); List <string> parents = new List <string>(); foreach (USN_RECORD_V2 usnRecord in usnData.OfType <USN_RECORD_V2>()) { parents.Clear(); USN_RECORD_V2 current = usnRecord; while (usnDic.ContainsKey(current.ParentFileReferenceNumber)) { current = usnDic[current.ParentFileReferenceNumber]; parents.Add(current.FileName); } parents.Reverse(); string path = Path.Combine(root, Path.Combine(parents.ToArray()), usnRecord.FileName); files.Add(path); } // Sort all files in lexicographical order files.Sort(); // FS Stats FileSystemStats[] fsStats; using (FilesystemDeviceWrapper fsIo = new FilesystemDeviceWrapper(volumeHandle)) fsStats = fsIo.FileSystemGetStatistics(); for (int i = 0; i < fsStats.Length; i++) { switch (fsStats[i].Stats.FileSystemType) { case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_NTFS: NTFS_STATISTICS ntfsStats = (NTFS_STATISTICS)fsStats[i].FSStats; Console.WriteLine("Processor {0}: (NTFS) MFT Reads/Writes: {1,7:N0} / {2,7:N0}", i, ntfsStats.MftReads, ntfsStats.MftWrites); break; case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_FAT: FAT_STATISTICS fatStats = (FAT_STATISTICS)fsStats[i].FSStats; Console.WriteLine("Processor {0}: (FAT) Noncached Disk Reads/Writes: {1,7:N0} / {2,7:N0}", i, fatStats.NonCachedDiskReads, fatStats.NonCachedDiskWrites); break; case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_EXFAT: EXFAT_STATISTICS exfatStats = (EXFAT_STATISTICS)fsStats[i].FSStats; Console.WriteLine("Processor {0}: (EXFAT) Noncached Disk Reads/Writes: {1,7:N0} / {2,7:N0}", i, exfatStats.NonCachedDiskReads, exfatStats.NonCachedDiskWrites); break; default: throw new ArgumentOutOfRangeException(); } } // Bitmap VOLUME_BITMAP_BUFFER bitmap; using (FilesystemDeviceWrapper fsIo = new FilesystemDeviceWrapper(volumeHandle)) bitmap = fsIo.FileSystemGetVolumeBitmap(0); Console.WriteLine("Bitmap: {0:N0} clusters", bitmap.Buffer.Length); int trues = 0, falses = 0; for (int i = 0; i < bitmap.Buffer.Length; i++) { if (bitmap.Buffer[i]) { trues++; } else { falses++; } } Console.WriteLine("Allocated clusters: {0:N0}", trues); Console.WriteLine("Unallocated clusters: {0:N0}", falses); // NTFS Base LCN (always 0) RETRIEVAL_POINTER_BASE basePointer; using (FilesystemDeviceWrapper fsIo = new FilesystemDeviceWrapper(volumeHandle)) basePointer = fsIo.FileSystemGetRetrievalPointerBase(); Console.WriteLine("Base LCN: {0:N0}", basePointer.FileAreaOffset); } Console.WriteLine(); }