ReactOS 0.4.15-dev-7934-g1dc8d80
fsinfo.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS FS utility tool
4 * FILE: base/applications/cmdutils/fsinfo.c
5 * PURPOSE: FSutil file systems information
6 * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7 */
8
9#include "fsutil.h"
10
11/* Add handlers here for subcommands */
18{
19 /* Proc, name, help */
20 { DrivesMain, _T("drives"), _T("Enumerates the drives") },
21 { DriveTypeMain, _T("drivetype"), _T("Provides the type of a drive") },
22 { VolumeInfoMain, _T("volumeinfo"), _T("Provides informations about a volume") },
23 { NtfsInfoMain, _T("ntfsinfo"), _T("Displays informations about a NTFS volume") },
24 { StatisticsMain, _T("statistics"), _T("Displays volume statistics") },
25};
26
27static int
28DrivesMain(int argc, const TCHAR *argv[])
29{
30 UINT i;
31 DWORD Drives;
32
33 /* Get the drives bitmap */
34 Drives = GetLogicalDrives();
35 if (Drives == 0)
36 {
38 return 1;
39 }
40
41 /* And output any found drive */
42 _ftprintf(stdout, _T("Drives:"));
43 for (i = 0; i < 26; i++)
44 {
45 if (Drives & (1 << i))
46 {
47 _ftprintf(stdout, _T(" %c:\\"), 'A' + i);
48 }
49 }
50 _ftprintf(stdout, _T("\n"));
51
52 return 0;
53}
54
55static int
57{
58 UINT Type;
59
60 /* We need a volume (letter) */
61 if (argc < 2)
62 {
63 _ftprintf(stderr, _T("Usage: fsutil fsinfo drivetype <volume>\n"));
64 _ftprintf(stderr, _T("\tFor example: fsutil fsinfo drivetype c:\n"));
65 return 1;
66 }
67
68 /* Get its drive type and make it readable */
70 switch (Type)
71 {
72 case DRIVE_UNKNOWN:
73 _ftprintf(stdout, _T("%s - unknown drive type\n"), argv[1]);
74 break;
75
77 _ftprintf(stdout, _T("%s - not a root directory\n"), argv[1]);
78 break;
79
80 case DRIVE_REMOVABLE:
81 _ftprintf(stdout, _T("%s - removable drive\n"), argv[1]);
82 break;
83
84 case DRIVE_FIXED:
85 _ftprintf(stdout, _T("%s - fixed drive\n"), argv[1]);
86 break;
87
88 case DRIVE_REMOTE:
89 _ftprintf(stdout, _T("%s - remote or network drive\n"), argv[1]);
90 break;
91
92 case DRIVE_CDROM:
93 _ftprintf(stdout, _T("%s - CD-ROM drive\n"), argv[1]);
94 break;
95
96 case DRIVE_RAMDISK:
97 _ftprintf(stdout, _T("%s - RAM disk drive\n"), argv[1]);
98 break;
99 }
100
101 return 0;
102}
103
104static int
106{
107 DWORD Serial, MaxComponentLen, Flags;
109
110#define HANDLE_FLAG(Flags, Flag, Desc) \
111 if (Flags & Flag) \
112 _ftprintf(stdout, Desc)
113
114 /* We need a volume (path) */
115 if (argc < 2)
116 {
117 _ftprintf(stderr, _T("Usage: fsutil fsinfo volumeinfo <volume_path>\n"));
118 _ftprintf(stderr, _T("\tFor example: fsutil fsinfo volumeinfo c:\\\n"));
119 return 1;
120 }
121
122 /* Gather information */
123 if (!GetVolumeInformation(argv[1], VolumeName, MAX_PATH + 1, &Serial,
124 &MaxComponentLen, &Flags, FileSystem, MAX_PATH + 1))
125 {
127 return 1;
128 }
129
130 /* Display general information */
131 _ftprintf(stdout, _T("Volume name: %s\n"), VolumeName);
132 _ftprintf(stdout, _T("Volume serial number: 0x%x\n"), Serial);
133 _ftprintf(stdout, _T("Maximum component length: %u\n"), MaxComponentLen);
134 _ftprintf(stdout, _T("File system name: %s\n"), FileSystem);
135
136 /* Display specific flags */
137 HANDLE_FLAG(Flags, FILE_CASE_SENSITIVE_SEARCH, _T("Supports case-sensitive file names\n"));
138 HANDLE_FLAG(Flags, FILE_CASE_PRESERVED_NAMES, _T("Supports preserved case of file names\n"));
139 HANDLE_FLAG(Flags, FILE_UNICODE_ON_DISK, _T("Supports unicode file names\n"));
140 HANDLE_FLAG(Flags, FILE_PERSISTENT_ACLS, _T("Preserves and applies ACLs\n"));
141 HANDLE_FLAG(Flags, FILE_FILE_COMPRESSION, _T("Supports compression per file\n"));
142 HANDLE_FLAG(Flags, FILE_VOLUME_QUOTAS, _T("Supports disk quotas\n"));
143 HANDLE_FLAG(Flags, FILE_SUPPORTS_SPARSE_FILES, _T("Supports sparse files\n"));
144 HANDLE_FLAG(Flags, FILE_SUPPORTS_REPARSE_POINTS, _T("Supports reparse points\n"));
145 HANDLE_FLAG(Flags, FILE_VOLUME_IS_COMPRESSED, _T("Is a compressed volume\n"));
146 HANDLE_FLAG(Flags, FILE_SUPPORTS_OBJECT_IDS, _T("Supports object identifiers\n"));
147 HANDLE_FLAG(Flags, FILE_SUPPORTS_ENCRYPTION, _T("Supports the Encrypted File System (EFS)\n"));
148 HANDLE_FLAG(Flags, FILE_NAMED_STREAMS, _T("Supports named streams\n"));
149 HANDLE_FLAG(Flags, FILE_READ_ONLY_VOLUME, _T("Is a read-only volume\n"));
150 HANDLE_FLAG(Flags, FILE_SEQUENTIAL_WRITE_ONCE, _T("Supports a single sequential write\n"));
151 HANDLE_FLAG(Flags, FILE_SUPPORTS_TRANSACTIONS, _T("Supports transactions\n"));
152 HANDLE_FLAG(Flags, FILE_SUPPORTS_HARD_LINKS, _T("Supports hard links\n"));
153 HANDLE_FLAG(Flags, FILE_SUPPORTS_EXTENDED_ATTRIBUTES, _T("Supports extended attributes\n"));
154 HANDLE_FLAG(Flags, FILE_SUPPORTS_OPEN_BY_FILE_ID, _T("Supports opening files per file identifier\n"));
155 HANDLE_FLAG(Flags, FILE_SUPPORTS_USN_JOURNAL, _T("Supports Update Sequence Number (USN) journals\n"));
156 HANDLE_FLAG(Flags, FILE_DAX_VOLUME, _T("Is a direct access volume\n"));
157
158#undef HANDLE_FLAGS
159
160 return 0;
161}
162
163static int
165{
168 struct
169 {
172 } Data;
173
174 /* We need a volume (letter or GUID) */
175 if (argc < 2)
176 {
177 _ftprintf(stderr, _T("Usage: fsutil fsinfo ntfsinfo <volume>\n"));
178 _ftprintf(stderr, _T("\tFor example: fsutil fsinfo ntfsinfo c:\n"));
179 return 1;
180 }
181
182 /* Get a handle for the volume */
185 {
186 return 1;
187 }
188
189 /* And query the NTFS data */
191 sizeof(Data), &BytesRead, NULL) == FALSE)
192 {
195 return 1;
196 }
197
198 /* We no longer need the volume */
200
201 /* Dump data */
202 _ftprintf(stdout, _T("NTFS volume serial number:\t\t0x%0.16I64x\n"), Data.VolumeSerialNumber.QuadPart);
203 /* Only print version if extended structure was returned */
205 {
206 _ftprintf(stdout, _T("Version:\t\t\t\t%u.%u\n"), Data.MajorVersion, Data.MinorVersion);
207 }
208 _ftprintf(stdout, _T("Number of sectors:\t\t\t0x%0.16I64x\n"), Data.NumberSectors.QuadPart);
209 _ftprintf(stdout, _T("Total number of clusters:\t\t0x%0.16I64x\n"), Data.TotalClusters.QuadPart);
210 _ftprintf(stdout, _T("Free clusters:\t\t\t\t0x%0.16I64x\n"), Data.FreeClusters.QuadPart);
211 _ftprintf(stdout, _T("Total number of reserved clusters:\t0x%0.16I64x\n"), Data.TotalReserved.QuadPart);
212 _ftprintf(stdout, _T("Bytes per sector:\t\t\t%d\n"), Data.BytesPerSector);
213 _ftprintf(stdout, _T("Bytes per cluster:\t\t\t%d\n"), Data.BytesPerCluster);
214 _ftprintf(stdout, _T("Bytes per file record segment:\t\t%d\n"), Data.BytesPerFileRecordSegment);
215 _ftprintf(stdout, _T("Clusters per file record segment:\t%d\n"), Data.ClustersPerFileRecordSegment);
216 _ftprintf(stdout, _T("MFT valid data length:\t\t\t0x%0.16I64x\n"), Data.MftValidDataLength.QuadPart);
217 _ftprintf(stdout, _T("MFT start LCN:\t\t\t\t0x%0.16I64x\n"), Data.MftStartLcn.QuadPart);
218 _ftprintf(stdout, _T("MFT2 start LCN:\t\t\t\t0x%0.16I64x\n"), Data.Mft2StartLcn.QuadPart);
219 _ftprintf(stdout, _T("MFT zone start:\t\t\t\t0x%0.16I64x\n"), Data.MftZoneStart.QuadPart);
220 _ftprintf(stdout, _T("MFT zone end:\t\t\t\t0x%0.16I64x\n"), Data.MftZoneEnd.QuadPart);
221
222 return 0;
223}
224
225#define DUMP_VALUE(stats, value) fprintf(stdout, "%s: %lu\n", #value, stats->value)
226
227static void
229{
230 /* Print FS name */
231 _ftprintf(stdout, _T("File system type: %s\n\n"), Name);
232
233 /* And then, dump any base stat */
234 DUMP_VALUE(Base, UserFileReads);
235 DUMP_VALUE(Base, UserFileReadBytes);
236 DUMP_VALUE(Base, UserDiskReads);
237 DUMP_VALUE(Base, UserFileWrites);
238 DUMP_VALUE(Base, UserFileWriteBytes);
239 DUMP_VALUE(Base, UserDiskWrites);
240 DUMP_VALUE(Base, MetaDataReads);
241 DUMP_VALUE(Base, MetaDataReadBytes);
242 DUMP_VALUE(Base, MetaDataDiskReads);
243 DUMP_VALUE(Base, MetaDataWrites);
244 DUMP_VALUE(Base, MetaDataWriteBytes);
245 DUMP_VALUE(Base, MetaDataDiskWrites);
246
247 _ftprintf(stdout, _T("\n"));
248}
249
250static void
251DumpExFat(PVOID Statistics, PVOID Specific)
252{
253 PEXFAT_STATISTICS ExFat;
255
256 Base = Statistics;
257 ExFat = Specific;
258
259 /* First, display the generic stats */
260 DumpBase(Base, _T("EXFAT"));
261
262 /* Then, display the EXFAT specific ones */
263 DUMP_VALUE(ExFat, CreateHits);
264 DUMP_VALUE(ExFat, SuccessfulCreates);
265 DUMP_VALUE(ExFat, FailedCreates);
266 DUMP_VALUE(ExFat, NonCachedReads);
267 DUMP_VALUE(ExFat, NonCachedReadBytes);
268 DUMP_VALUE(ExFat, NonCachedWrites);
269 DUMP_VALUE(ExFat, NonCachedWriteBytes);
270 DUMP_VALUE(ExFat, NonCachedDiskReads);
271 DUMP_VALUE(ExFat, NonCachedDiskWrites);
272}
273
274static void
275DumpFat(PVOID Statistics, PVOID Specific)
276{
277 PFAT_STATISTICS Fat;
279
280 Base = Statistics;
281 Fat = Specific;
282
283 /* First, display the generic stats */
284 DumpBase(Base, _T("FAT"));
285
286 /* Then, display the FAT specific ones */
287 DUMP_VALUE(Fat, CreateHits);
288 DUMP_VALUE(Fat, SuccessfulCreates);
289 DUMP_VALUE(Fat, FailedCreates);
290 DUMP_VALUE(Fat, NonCachedReads);
291 DUMP_VALUE(Fat, NonCachedReadBytes);
292 DUMP_VALUE(Fat, NonCachedWrites);
293 DUMP_VALUE(Fat, NonCachedWriteBytes);
294 DUMP_VALUE(Fat, NonCachedDiskReads);
295 DUMP_VALUE(Fat, NonCachedDiskWrites);
296}
297
298static void
299DumpNtfs(PVOID Statistics, PVOID Specific)
300{
301 PNTFS_STATISTICS Ntfs;
303
304 Base = Statistics;
305 Ntfs = Specific;
306
307 /* First, display the generic stats */
308 DumpBase(Base, _T("NTFS"));
309
310 /* Then, display the NTFS specific ones */
311 DUMP_VALUE(Ntfs, MftReads);
312 DUMP_VALUE(Ntfs, MftReadBytes);
313 DUMP_VALUE(Ntfs, MftWrites);
314 DUMP_VALUE(Ntfs, MftWriteBytes);
315 DUMP_VALUE(Ntfs, Mft2Writes);
316 DUMP_VALUE(Ntfs, Mft2WriteBytes);
317 DUMP_VALUE(Ntfs, RootIndexReads);
318 DUMP_VALUE(Ntfs, RootIndexReadBytes);
319 DUMP_VALUE(Ntfs, RootIndexWrites);
320 DUMP_VALUE(Ntfs, RootIndexWriteBytes);
321 DUMP_VALUE(Ntfs, BitmapReads);
322 DUMP_VALUE(Ntfs, BitmapReadBytes);
323 DUMP_VALUE(Ntfs, BitmapWrites);
324 DUMP_VALUE(Ntfs, BitmapWriteBytes);
325 DUMP_VALUE(Ntfs, MftBitmapReads);
326 DUMP_VALUE(Ntfs, MftBitmapReadBytes);
327 DUMP_VALUE(Ntfs, MftBitmapWrites);
328 DUMP_VALUE(Ntfs, MftBitmapWriteBytes);
329 DUMP_VALUE(Ntfs, UserIndexReads);
330 DUMP_VALUE(Ntfs, UserIndexReadBytes);
331 DUMP_VALUE(Ntfs, UserIndexWrites);
332 DUMP_VALUE(Ntfs, UserIndexWriteBytes);
333 DUMP_VALUE(Ntfs, LogFileReads);
334 DUMP_VALUE(Ntfs, LogFileReadBytes);
335 DUMP_VALUE(Ntfs, LogFileWrites);
336 DUMP_VALUE(Ntfs, LogFileWriteBytes);
337}
338
339#define GET_NEXT(stats, length, iter, type) (type)((ULONG_PTR)stats + (length * iter))
340#define SUM_VALUE(stats, new, value) stats->value += new->value
341
342static inline int
344{
345 /* Check whether we could read our base length for every processor */
346 if (Length * ProcCount > BytesRead)
347 {
348 _ftprintf(stderr, _T("Only performed a partial read: %lu (expected: %lu)\n"), BytesRead, Length * ProcCount);
349 return 1;
350 }
351
352 /* Check whether this covers a specific entry and a generic entry for every processor */
353 if ((sizeof(FILESYSTEM_STATISTICS) + SpecificSize) * ProcCount > BytesRead)
354 {
355 _ftprintf(stderr, _T("Only performed a partial read: %lu (expected: %Iu)\n"), BytesRead, (sizeof(FILESYSTEM_STATISTICS) + SpecificSize));
356 return 1;
357 }
358
359 return 0;
360}
361
362static inline void
364{
365 /* Sum any entry in the generic structures */
366 SUM_VALUE(Base, NextBase, UserFileReads);
367 SUM_VALUE(Base, NextBase, UserFileReadBytes);
368 SUM_VALUE(Base, NextBase, UserDiskReads);
369 SUM_VALUE(Base, NextBase, UserFileWrites);
370 SUM_VALUE(Base, NextBase, UserFileWriteBytes);
371 SUM_VALUE(Base, NextBase, UserDiskWrites);
372 SUM_VALUE(Base, NextBase, MetaDataReads);
373 SUM_VALUE(Base, NextBase, MetaDataReadBytes);
374 SUM_VALUE(Base, NextBase, MetaDataDiskReads);
375 SUM_VALUE(Base, NextBase, MetaDataWrites);
376 SUM_VALUE(Base, NextBase, MetaDataWriteBytes);
377 SUM_VALUE(Base, NextBase, MetaDataDiskWrites);
378}
379
380static int
381SumExFat(PVOID Statistics, PVOID Specific, ULONG Length, DWORD ProcCount, DWORD BytesRead)
382{
383 DWORD i;
384 PEXFAT_STATISTICS ExFat;
386
387 /* First, validate we won't read beyond allocation */
388 if (ValidateSizes(Length, ProcCount, BytesRead, sizeof(EXFAT_STATISTICS)))
389 {
390 return 1;
391 }
392
393 Base = Statistics;
394 ExFat = Specific;
395
396 /* And for every processor, sum every relevant value in first entry */
397 for (i = 1; i < ProcCount; ++i)
398 {
399 PEXFAT_STATISTICS NextExFat;
400 PFILESYSTEM_STATISTICS NextBase;
401
403 NextExFat = GET_NEXT(ExFat, Length, i, PEXFAT_STATISTICS);
404
405 /* Generic first */
406 SumBase(Base, NextBase);
407 /* Specific then */
408 SUM_VALUE(ExFat, NextExFat, CreateHits);
409 SUM_VALUE(ExFat, NextExFat, SuccessfulCreates);
410 SUM_VALUE(ExFat, NextExFat, FailedCreates);
411 SUM_VALUE(ExFat, NextExFat, NonCachedReads);
412 SUM_VALUE(ExFat, NextExFat, NonCachedReadBytes);
413 SUM_VALUE(ExFat, NextExFat, NonCachedWrites);
414 SUM_VALUE(ExFat, NextExFat, NonCachedWriteBytes);
415 SUM_VALUE(ExFat, NextExFat, NonCachedDiskReads);
416 SUM_VALUE(ExFat, NextExFat, NonCachedDiskWrites);
417 }
418
419 return 0;
420}
421
422static int
423SumFat(PVOID Statistics, PVOID Specific, ULONG Length, DWORD ProcCount, DWORD BytesRead)
424{
425 DWORD i;
426 PFAT_STATISTICS Fat;
428
429 /* First, validate we won't read beyond allocation */
430 if (ValidateSizes(Length, ProcCount, BytesRead, sizeof(FAT_STATISTICS)))
431 {
432 return 1;
433 }
434
435 Base = Statistics;
436 Fat = Specific;
437
438 /* And for every processor, sum every relevant value in first entry */
439 for (i = 1; i < ProcCount; ++i)
440 {
441 PFAT_STATISTICS NextFat;
442 PFILESYSTEM_STATISTICS NextBase;
443
445 NextFat = GET_NEXT(Fat, Length, i, PFAT_STATISTICS);
446
447 /* Generic first */
448 SumBase(Base, NextBase);
449 /* Specific then */
450 SUM_VALUE(Fat, NextFat, CreateHits);
451 SUM_VALUE(Fat, NextFat, SuccessfulCreates);
452 SUM_VALUE(Fat, NextFat, FailedCreates);
453 SUM_VALUE(Fat, NextFat, NonCachedReads);
454 SUM_VALUE(Fat, NextFat, NonCachedReadBytes);
455 SUM_VALUE(Fat, NextFat, NonCachedWrites);
456 SUM_VALUE(Fat, NextFat, NonCachedWriteBytes);
457 SUM_VALUE(Fat, NextFat, NonCachedDiskReads);
458 SUM_VALUE(Fat, NextFat, NonCachedDiskWrites);
459 }
460
461 return 0;
462}
463
464static int
465SumNtfs(PVOID Statistics, PVOID Specific, ULONG Length, DWORD ProcCount, DWORD BytesRead)
466{
467 DWORD i;
468 PNTFS_STATISTICS Ntfs;
470
471 /* First, validate we won't read beyond allocation */
472 if (ValidateSizes(Length, ProcCount, BytesRead, sizeof(NTFS_STATISTICS)))
473 {
474 return 1;
475 }
476
477 Base = Statistics;
478 Ntfs = Specific;
479
480 /* And for every processor, sum every relevant value in first entry */
481 for (i = 1; i < ProcCount; ++i)
482 {
483 PNTFS_STATISTICS NextNtfs;
484 PFILESYSTEM_STATISTICS NextBase;
485
487 NextNtfs = GET_NEXT(Ntfs, Length, i, PNTFS_STATISTICS);
488
489 /* Generic first */
490 SumBase(Base, NextBase);
491 /* Specific then */
492 SUM_VALUE(Ntfs, NextNtfs, MftReads);
493 SUM_VALUE(Ntfs, NextNtfs, MftReadBytes);
494 SUM_VALUE(Ntfs, NextNtfs, MftWrites);
495 SUM_VALUE(Ntfs, NextNtfs, MftWriteBytes);
496 SUM_VALUE(Ntfs, NextNtfs, Mft2Writes);
497 SUM_VALUE(Ntfs, NextNtfs, Mft2WriteBytes);
498 SUM_VALUE(Ntfs, NextNtfs, RootIndexReads);
499 SUM_VALUE(Ntfs, NextNtfs, RootIndexReadBytes);
500 SUM_VALUE(Ntfs, NextNtfs, RootIndexWrites);
501 SUM_VALUE(Ntfs, NextNtfs, RootIndexWriteBytes);
502 SUM_VALUE(Ntfs, NextNtfs, BitmapReads);
503 SUM_VALUE(Ntfs, NextNtfs, BitmapReadBytes);
504 SUM_VALUE(Ntfs, NextNtfs, BitmapWrites);
505 SUM_VALUE(Ntfs, NextNtfs, BitmapWriteBytes);
506 SUM_VALUE(Ntfs, NextNtfs, MftBitmapReads);
507 SUM_VALUE(Ntfs, NextNtfs, MftBitmapReadBytes);
508 SUM_VALUE(Ntfs, NextNtfs, MftBitmapWrites);
509 SUM_VALUE(Ntfs, NextNtfs, MftBitmapWriteBytes);
510 SUM_VALUE(Ntfs, NextNtfs, UserIndexReads);
511 SUM_VALUE(Ntfs, NextNtfs, UserIndexReadBytes);
512 SUM_VALUE(Ntfs, NextNtfs, UserIndexWrites);
513 SUM_VALUE(Ntfs, NextNtfs, UserIndexWriteBytes);
514 SUM_VALUE(Ntfs, NextNtfs, LogFileReads);
515 SUM_VALUE(Ntfs, NextNtfs, LogFileReadBytes);
516 SUM_VALUE(Ntfs, NextNtfs, LogFileWrites);
517 SUM_VALUE(Ntfs, NextNtfs, LogFileWriteBytes);
518 }
519
520 return 0;
521}
522
523static int
525{
527 SYSTEM_INFO SystemInfo;
529 PFILESYSTEM_STATISTICS Statistics;
530 DWORD BytesRead, Length, ProcCount;
531 /* +1 because 0 isn't assigned to a filesystem */
534
535 /* We need a volume (letter or GUID) */
536 if (argc < 2)
537 {
538 _ftprintf(stderr, _T("Usage: fsutil fsinfo statistics <volume>\n"));
539 _ftprintf(stderr, _T("\tFor example: fsutil fsinfo statistics c:\n"));
540 return 1;
541 }
542
543 /* Get a handle for the volume */
546 {
547 return 1;
548 }
549
550 /* And query the statistics status - this call is expected to fail */
551 Statistics = &Buffer;
552 Length = sizeof(Buffer);
553 /* Assume we have a single proc for now */
554 ProcCount = 1;
556 Length, &BytesRead, NULL) == FALSE)
557 {
558 DWORD Error;
559
560 /* Check we failed because we provided a too small buffer */
562 if (Error == ERROR_MORE_DATA)
563 {
564 /* Get proc count */
565 GetSystemInfo(&SystemInfo);
566 ProcCount = SystemInfo.dwNumberOfProcessors;
567 /* Get the maximum size to allocate: it's the total size (generic + specific) for every proc */
568 Length = Statistics->SizeOfCompleteStructure * ProcCount;
569
570 Statistics = LocalAlloc(LPTR, Length);
571 if (Statistics == NULL)
572 {
573 _ftprintf(stderr, _T("Failed to allocate memory!\n"));
575 return 1;
576 }
577
578 /* Reissue the FSCTL, it's supposed to succeed now! */
580 Length, &BytesRead, NULL) == FALSE)
581 {
583 LocalFree(Statistics);
585 return 1;
586 }
587 }
588 else
589 {
592 return 1;
593 }
594 }
595
596 /* No need to deal with the volume any longer */
598
599 /* We only support FAT, EXFAT and NTFS for now */
601 {
602 _ftprintf(stderr, _T("Unrecognized file system type: %d\n"), Statistics->FileSystemType);
603 if (Statistics != &Buffer)
604 {
605 LocalFree(Statistics);
606 }
607
608 return 1;
609 }
610
611 /* Sum all the statistics (both generic and specific) from all the processors in the first entry */
612 if (SumFct[Statistics->FileSystemType](Statistics, (PVOID)((ULONG_PTR)Statistics + sizeof(FILESYSTEM_STATISTICS)),
613 Statistics->SizeOfCompleteStructure, ProcCount, BytesRead))
614 {
615 if (Statistics != &Buffer)
616 {
617 LocalFree(Statistics);
618 }
619
620 return 1;
621 }
622
623 /* And finally, display the statistics (both generic and specific) */
624 DumpFct[Statistics->FileSystemType](Statistics, (PVOID)((ULONG_PTR)Statistics + sizeof(FILESYSTEM_STATISTICS)));
625
626 /* If we allocated memory, release it */
627 if (Statistics != &Buffer)
628 {
629 LocalFree(Statistics);
630 }
631
632 return 0;
633}
634
635static void
637{
639 (sizeof(HandlersList) / sizeof(HandlersList[0])));
640}
641
642int
643FsInfoMain(int argc, const TCHAR *argv[])
644{
646 (sizeof(HandlersList) / sizeof(HandlersList[0])),
647 PrintUsage);
648}
static int argc
Definition: ServiceArgs.c:12
Type
Definition: Type.h:7
HandlerProc FsInfoMain
Definition: fsutil.c:13
int() HandlerProc(int argc, const TCHAR *argv[])
Definition: fsutil.h:8
static VOID PrintErrorMessage(DWORD dwError)
Definition: at.c:308
HANDLE OpenVolume(const TCHAR *Volume, BOOLEAN AllowRemote, BOOLEAN NtfsOnly)
Definition: common.c:49
void PrintDefaultUsage(const TCHAR *Command, const TCHAR *SubCommand, HandlerItem *HandlersList, int HandlerListCount)
Definition: common.c:102
int FindHandler(int argc, const TCHAR *argv[], HandlerItem *HandlersList, int HandlerListCount, void(*UsageHelper)(const TCHAR *))
Definition: common.c:11
BOOL Error
Definition: chkdsk.c:66
PWCHAR FileSystem
Definition: format.c:72
Definition: bufpool.h:45
#define ERROR_MORE_DATA
Definition: dderror.h:13
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
#define FILE_SUPPORTS_TRANSACTIONS
Definition: from_kernel.h:248
#define FILE_SUPPORTS_ENCRYPTION
Definition: from_kernel.h:244
#define FILE_NAMED_STREAMS
Definition: from_kernel.h:245
#define FILE_SUPPORTS_USN_JOURNAL
Definition: from_kernel.h:252
#define FILE_SUPPORTS_EXTENDED_ATTRIBUTES
Definition: from_kernel.h:250
#define FILE_SEQUENTIAL_WRITE_ONCE
Definition: from_kernel.h:247
#define FILE_SUPPORTS_SPARSE_FILES
Definition: from_kernel.h:239
#define FILE_SUPPORTS_REPARSE_POINTS
Definition: from_kernel.h:240
#define FILE_READ_ONLY_VOLUME
Definition: from_kernel.h:246
#define FILE_FILE_COMPRESSION
Definition: from_kernel.h:237
#define FILE_SUPPORTS_HARD_LINKS
Definition: from_kernel.h:249
#define FILE_SUPPORTS_OBJECT_IDS
Definition: from_kernel.h:243
#define FILE_VOLUME_IS_COMPRESSED
Definition: from_kernel.h:242
#define FILE_PERSISTENT_ACLS
Definition: from_kernel.h:236
#define FILE_CASE_SENSITIVE_SEARCH
Definition: from_kernel.h:233
#define FILE_CASE_PRESERVED_NAMES
Definition: from_kernel.h:234
#define FILE_VOLUME_QUOTAS
Definition: from_kernel.h:238
#define FILE_SUPPORTS_OPEN_BY_FILE_ID
Definition: from_kernel.h:251
#define FILE_UNICODE_ON_DISK
Definition: from_kernel.h:235
static HandlerProc DriveTypeMain
Definition: fsinfo.c:13
static int SumNtfs(PVOID Statistics, PVOID Specific, ULONG Length, DWORD ProcCount, DWORD BytesRead)
Definition: fsinfo.c:465
static HandlerProc VolumeInfoMain
Definition: fsinfo.c:14
static void SumBase(PFILESYSTEM_STATISTICS Base, PFILESYSTEM_STATISTICS NextBase)
Definition: fsinfo.c:363
#define GET_NEXT(stats, length, iter, type)
Definition: fsinfo.c:339
#define HANDLE_FLAG(Flags, Flag, Desc)
static void DumpFat(PVOID Statistics, PVOID Specific)
Definition: fsinfo.c:275
#define SUM_VALUE(stats, new, value)
Definition: fsinfo.c:340
static void DumpNtfs(PVOID Statistics, PVOID Specific)
Definition: fsinfo.c:299
static void DumpExFat(PVOID Statistics, PVOID Specific)
Definition: fsinfo.c:251
static int ValidateSizes(ULONG Length, DWORD ProcCount, DWORD BytesRead, DWORD SpecificSize)
Definition: fsinfo.c:343
static int SumFat(PVOID Statistics, PVOID Specific, ULONG Length, DWORD ProcCount, DWORD BytesRead)
Definition: fsinfo.c:423
static HandlerProc DrivesMain
Definition: fsinfo.c:12
static HandlerProc StatisticsMain
Definition: fsinfo.c:16
static void DumpBase(PFILESYSTEM_STATISTICS Base, TCHAR *Name)
Definition: fsinfo.c:228
static HandlerItem HandlersList[]
Definition: fsinfo.c:17
#define DUMP_VALUE(stats, value)
Definition: fsinfo.c:225
static int SumExFat(PVOID Statistics, PVOID Specific, ULONG Length, DWORD ProcCount, DWORD BytesRead)
Definition: fsinfo.c:381
static HandlerProc NtfsInfoMain
Definition: fsinfo.c:15
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define stdout
Definition: stdio.h:99
#define stderr
Definition: stdio.h:100
#define _ftprintf
Definition: tchar.h:518
#define DRIVE_CDROM
Definition: machpc98.h:119
UNICODE_STRING Volume
Definition: fltkernel.h:1172
#define argv
Definition: mplay32.c:18
unsigned int UINT
Definition: ndis.h:50
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
void PrintUsage()
Definition: nslookup.c:68
#define FSCTL_FILESYSTEM_GET_STATISTICS
Definition: nt_native.h:850
#define DWORD
Definition: nt_native.h:44
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define FSCTL_GET_NTFS_VOLUME_DATA
Definition: ntifs_ex.h:261
#define FILESYSTEM_STATISTICS_TYPE_EXFAT
Definition: winioctl.h:752
#define FILESYSTEM_STATISTICS_TYPE_NTFS
Definition: winioctl.h:750
struct _FILESYSTEM_STATISTICS FILESYSTEM_STATISTICS
Definition: shell.h:41
ULONG SizeOfCompleteStructure
Definition: winioctl.h:735
DWORD dwNumberOfProcessors
Definition: winbase.h:1177
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define _T(x)
Definition: vfdio.h:22
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
#define DRIVE_UNKNOWN
Definition: winbase.h:256
#define DRIVE_NO_ROOT_DIR
Definition: winbase.h:257
#define GetVolumeInformation
Definition: winbase.h:3853
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GetDriveType
Definition: winbase.h:3812
#define DRIVE_REMOTE
Definition: winbase.h:253
#define LPTR
Definition: winbase.h:381
DWORD WINAPI GetLogicalDrives(void)
Definition: disk.c:110
#define DRIVE_RAMDISK
Definition: winbase.h:255
#define DRIVE_FIXED
Definition: winbase.h:252
#define DRIVE_REMOVABLE
Definition: winbase.h:251
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define FILE_DAX_VOLUME
char TCHAR
Definition: xmlstorage.h:189