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
ShowFileSystemInfo(PVOLENTRY VolumeEntry)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
ShowInstalledFileSystems(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
filesystems_main(_In_ INT argc,_In_ PWSTR * argv)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