xref: /reactos/base/system/diskpart/filesystems.c (revision d6eebaa4)
1 /*
2  * PROJECT:         ReactOS DiskPart
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            base/system/diskpart/filesystems.c
5  * PURPOSE:         Manages all the partitions of the OS in an interactive way.
6  * PROGRAMMERS:     Lee Schroeder
7  */
8 
9 #include "diskpart.h"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 static
15 BOOL
16 ShowFileSystemInfo(
17     PVOLENTRY VolumeEntry)
18 {
19     WCHAR VolumeNameBuffer[MAX_PATH];
20     UNICODE_STRING VolumeName;
21     HANDLE VolumeHandle;
22     OBJECT_ATTRIBUTES ObjectAttributes;
23     IO_STATUS_BLOCK IoStatusBlock;
24     ULONG ulSize, ulClusterSize = 0;
25     FILE_FS_FULL_SIZE_INFORMATION SizeInfo;
26     FILE_FS_FULL_SIZE_INFORMATION FullSizeInfo;
27     PFILE_FS_ATTRIBUTE_INFORMATION pAttributeInfo = NULL;
28     NTSTATUS Status;
29     BOOL Result = TRUE;
30 
31     wcscpy(VolumeNameBuffer, VolumeEntry->DeviceName);
32     wcscat(VolumeNameBuffer, L"\\");
33 
34     RtlInitUnicodeString(&VolumeName, VolumeNameBuffer);
35 
36     InitializeObjectAttributes(&ObjectAttributes,
37                                &VolumeName,
38                                0,
39                                NULL,
40                                NULL);
41 
42     Status = NtOpenFile(&VolumeHandle,
43                         SYNCHRONIZE,
44                         &ObjectAttributes,
45                         &IoStatusBlock,
46                         0,
47                         FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT);
48     if (!NT_SUCCESS(Status))
49     {
50         if (Status == STATUS_NO_MEDIA_IN_DEVICE)
51         {
52             ConResPuts(StdOut, IDS_ERROR_NO_MEDIUM);
53             return FALSE;
54         }
55         else if (Status == STATUS_UNRECOGNIZED_VOLUME)
56         {
57             ConResPuts(StdOut, IDS_FILESYSTEMS_CURRENT);
58             ConPuts(StdOut, L"\n");
59             ConResPrintf(StdOut, IDS_FILESYSTEMS_TYPE, L"RAW");
60             ConResPrintf(StdOut, IDS_FILESYSTEMS_CLUSTERSIZE, 512);
61         }
62 
63         return TRUE;
64     }
65 
66     ulSize = sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 255 * sizeof(WCHAR);
67     pAttributeInfo = RtlAllocateHeap(RtlGetProcessHeap(),
68                                      HEAP_ZERO_MEMORY,
69                                      ulSize);
70     if (pAttributeInfo == NULL)
71     {
72         Result = FALSE;
73         goto done;
74     }
75 
76     Status = NtQueryVolumeInformationFile(VolumeHandle,
77                                           &IoStatusBlock,
78                                           pAttributeInfo,
79                                           ulSize,
80                                           FileFsAttributeInformation);
81     if (!NT_SUCCESS(Status))
82     {
83         Result = FALSE;
84         goto done;
85     }
86 
87     Status = NtQueryVolumeInformationFile(VolumeHandle,
88                                           &IoStatusBlock,
89                                           &FullSizeInfo,
90                                           sizeof(FILE_FS_FULL_SIZE_INFORMATION),
91                                           FileFsFullSizeInformation);
92     if (NT_SUCCESS(Status))
93     {
94         ulClusterSize  = FullSizeInfo.BytesPerSector * FullSizeInfo.SectorsPerAllocationUnit;
95     }
96     else
97     {
98         Status = NtQueryVolumeInformationFile(VolumeHandle,
99                                               &IoStatusBlock,
100                                               &SizeInfo,
101                                               sizeof(FILE_FS_SIZE_INFORMATION),
102                                               FileFsSizeInformation);
103         if (NT_SUCCESS(Status))
104         {
105             ulClusterSize  = SizeInfo.BytesPerSector * SizeInfo.SectorsPerAllocationUnit;
106         }
107     }
108 
109 
110     ConResPuts(StdOut, IDS_FILESYSTEMS_CURRENT);
111     ConPuts(StdOut, L"\n");
112 
113     ConResPrintf(StdOut, IDS_FILESYSTEMS_TYPE, pAttributeInfo->FileSystemName);
114     ConResPrintf(StdOut, IDS_FILESYSTEMS_CLUSTERSIZE, ulClusterSize);
115     ConPuts(StdOut, L"\n");
116 
117 done:
118     if (pAttributeInfo)
119         RtlFreeHeap(RtlGetProcessHeap(), 0, pAttributeInfo);
120 
121     NtClose(VolumeHandle);
122 
123     return Result;
124 }
125 
126 static
127 VOID
128 ShowInstalledFileSystems(VOID)
129 {
130     WCHAR szBuffer[256];
131     BOOLEAN ret;
132     DWORD dwIndex;
133     UCHAR uMajor, uMinor;
134     BOOLEAN bLatest;
135 
136     ConResPuts(StdOut, IDS_FILESYSTEMS_FORMATTING);
137 
138     for (dwIndex = 0; ; dwIndex++)
139     {
140         ret = QueryAvailableFileSystemFormat(dwIndex,
141                                              szBuffer,
142                                              &uMajor,
143                                              &uMinor,
144                                             &bLatest);
145         if (ret == FALSE)
146             break;
147 
148         ConPrintf(StdOut, L"  %s\n", szBuffer);
149     }
150 
151     ConPuts(StdOut, L"\n");
152 }
153 
154 BOOL
155 filesystems_main(
156     _In_ INT argc,
157     _In_ PWSTR *argv)
158 {
159     if (CurrentVolume == NULL)
160     {
161         ConResPuts(StdOut, IDS_SELECT_NO_VOLUME);
162         return TRUE;
163     }
164 
165     ConPuts(StdOut, L"\n");
166 
167     if (ShowFileSystemInfo(CurrentVolume))
168     {
169         ShowInstalledFileSystems();
170     }
171 
172     return TRUE;
173 }
174