27
27
import java .util .HashMap ;
28
28
import java .util .List ;
29
29
import java .util .Map ;
30
+ import java .util .stream .Collectors ;
30
31
31
32
import com .sun .jna .platform .win32 .Kernel32 ; //NOSONAR
32
33
import com .sun .jna .platform .win32 .WinBase ;
33
34
import com .sun .jna .platform .win32 .WinNT ;
34
35
import com .sun .jna .platform .win32 .COM .WbemcliUtil .WmiQuery ;
35
36
import com .sun .jna .platform .win32 .COM .WbemcliUtil .WmiResult ;
37
+ import com .sun .jna .ptr .IntByReference ;
36
38
37
39
import oshi .software .common .AbstractFileSystem ;
38
40
import oshi .software .os .OSFileStore ;
@@ -55,6 +57,44 @@ public class WindowsFileSystem extends AbstractFileSystem {
55
57
56
58
private static final int SEM_FAILCRITICALERRORS = 0x0001 ;
57
59
60
+ private static final int FILE_CASE_SENSITIVE_SEARCH = 0x00000001 ;
61
+ private static final int FILE_CASE_PRESERVED_NAMES = 0x00000002 ;
62
+ private static final int FILE_FILE_COMPRESSION = 0x00000010 ;
63
+ private static final int FILE_DAX_VOLUME = 0x20000000 ;
64
+ private static final int FILE_NAMED_STREAMS = 0x00040000 ;
65
+ private static final int FILE_PERSISTENT_ACLS = 0x00000008 ;
66
+ private static final int FILE_READ_ONLY_VOLUME = 0x00080000 ;
67
+ private static final int FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000 ;
68
+ private static final int FILE_SUPPORTS_ENCRYPTION = 0x00020000 ;
69
+ private static final int FILE_SUPPORTS_OBJECT_IDS = 0x00010000 ;
70
+ private static final int FILE_SUPPORTS_REPARSE_POINTS = 0x00000080 ;
71
+ private static final int FILE_SUPPORTS_SPARSE_FILES = 0x00000040 ;
72
+ private static final int FILE_SUPPORTS_TRANSACTIONS = 0x00200000 ;
73
+ private static final int FILE_SUPPORTS_USN_JOURNAL = 0x02000000 ;
74
+ private static final int FILE_UNICODE_ON_DISK = 0x00000004 ;
75
+ private static final int FILE_VOLUME_IS_COMPRESSED = 0x00008000 ;
76
+ private static final int FILE_VOLUME_QUOTAS = 0x00000020 ;
77
+
78
+ private static final Map <Integer , String > OPTIONS_MAP = new HashMap <>();
79
+ static {
80
+ OPTIONS_MAP .put (FILE_CASE_PRESERVED_NAMES , "casepn" );
81
+ OPTIONS_MAP .put (FILE_CASE_SENSITIVE_SEARCH , "casess" );
82
+ OPTIONS_MAP .put (FILE_FILE_COMPRESSION , "fcomp" );
83
+ OPTIONS_MAP .put (FILE_DAX_VOLUME , "dax" );
84
+ OPTIONS_MAP .put (FILE_NAMED_STREAMS , "streams" );
85
+ OPTIONS_MAP .put (FILE_PERSISTENT_ACLS , "acls" );
86
+ OPTIONS_MAP .put (FILE_SEQUENTIAL_WRITE_ONCE , "wronce" );
87
+ OPTIONS_MAP .put (FILE_SUPPORTS_ENCRYPTION , "efs" );
88
+ OPTIONS_MAP .put (FILE_SUPPORTS_OBJECT_IDS , "oids" );
89
+ OPTIONS_MAP .put (FILE_SUPPORTS_REPARSE_POINTS , "reparse" );
90
+ OPTIONS_MAP .put (FILE_SUPPORTS_SPARSE_FILES , "sparse" );
91
+ OPTIONS_MAP .put (FILE_SUPPORTS_TRANSACTIONS , "trans" );
92
+ OPTIONS_MAP .put (FILE_SUPPORTS_USN_JOURNAL , "journaled" );
93
+ OPTIONS_MAP .put (FILE_UNICODE_ON_DISK , "unicode" );
94
+ OPTIONS_MAP .put (FILE_VOLUME_IS_COMPRESSED , "vcomp" );
95
+ OPTIONS_MAP .put (FILE_VOLUME_QUOTAS , "quota" );
96
+ }
97
+
58
98
enum LogicalDiskProperty {
59
99
DESCRIPTION , DRIVETYPE , FILESYSTEM , FREESPACE , NAME , PROVIDERNAME , SIZE ;
60
100
}
@@ -157,6 +197,7 @@ private static ArrayList<OSFileStore> getLocalVolumes(String nameToMatch) {
157
197
char [] fstype ;
158
198
char [] name ;
159
199
char [] mount ;
200
+ IntByReference pFlags ;
160
201
161
202
fs = new ArrayList <>();
162
203
aVolume = new char [BUFSIZE ];
@@ -170,36 +211,47 @@ private static ArrayList<OSFileStore> getLocalVolumes(String nameToMatch) {
170
211
fstype = new char [16 ];
171
212
name = new char [BUFSIZE ];
172
213
mount = new char [BUFSIZE ];
214
+ pFlags = new IntByReference ();
173
215
174
216
userFreeBytes = new WinNT .LARGE_INTEGER (0L );
175
217
totalBytes = new WinNT .LARGE_INTEGER (0L );
176
218
systemFreeBytes = new WinNT .LARGE_INTEGER (0L );
177
219
178
220
volume = new String (aVolume ).trim ();
179
- Kernel32 .INSTANCE .GetVolumeInformation (volume , name , BUFSIZE , null , null , null , fstype , 16 );
221
+ Kernel32 .INSTANCE .GetVolumeInformation (volume , name , BUFSIZE , null , null , pFlags , fstype , 16 );
222
+ final int flags = pFlags .getValue ();
180
223
Kernel32 .INSTANCE .GetVolumePathNamesForVolumeName (volume , mount , BUFSIZE , null );
181
224
182
225
strMount = new String (mount ).trim ();
183
- strName = new String (name ).trim ();
184
- strFsType = new String (fstype ).trim ();
185
- String osName = String .format ("%s (%s)" , strName , strMount );
186
- if (nameToMatch == null || nameToMatch .equals (osName )) {
187
- Kernel32 .INSTANCE .GetDiskFreeSpaceEx (volume , userFreeBytes , totalBytes , systemFreeBytes );
188
- // Parse uuid from volume name
189
- String uuid = ParseUtil .parseUuidOrDefault (volume , "" );
190
-
191
- if (!strMount .isEmpty ()) {
226
+ if (!strMount .isEmpty ()) {
227
+ strName = new String (name ).trim ();
228
+ strFsType = new String (fstype ).trim ();
229
+
230
+ StringBuilder options = new StringBuilder ((FILE_READ_ONLY_VOLUME & flags ) == 0 ? "rw" : "ro" );
231
+ String moreOptions = OPTIONS_MAP .entrySet ().stream ().filter (e -> (e .getKey () & flags ) > 0 )
232
+ .map (Map .Entry ::getValue ).collect (Collectors .joining ("," ));
233
+ if (!moreOptions .isEmpty ()) {
234
+ options .append (',' ).append (moreOptions );
235
+ }
236
+ String osName = String .format ("%s (%s)" , strName , strMount );
237
+ if (nameToMatch == null || nameToMatch .equals (osName )) {
238
+ Kernel32 .INSTANCE .GetDiskFreeSpaceEx (volume , userFreeBytes , totalBytes , systemFreeBytes );
239
+ // Parse uuid from volume name
240
+ String uuid = ParseUtil .parseUuidOrDefault (volume , "" );
241
+
192
242
// Volume is mounted
193
243
OSFileStore osStore = new OSFileStore ();
194
244
osStore .setName (osName );
195
245
osStore .setVolume (volume );
196
246
osStore .setMount (strMount );
197
247
osStore .setDescription (getDriveType (strMount ));
198
248
osStore .setType (strFsType );
249
+ osStore .setOptions (options .toString ());
199
250
osStore .setUUID (uuid );
200
251
osStore .setFreeSpace (systemFreeBytes .getValue ());
201
252
osStore .setUsableSpace (userFreeBytes .getValue ());
202
253
osStore .setTotalSpace (totalBytes .getValue ());
254
+ System .out .println (osStore .toString ());
203
255
fs .add (osStore );
204
256
}
205
257
}
@@ -238,7 +290,8 @@ private static List<OSFileStore> getWmiVolumes(String nameToMatch, boolean local
238
290
wmiClassName .append (where ? " WHERE" : " AND" ).append (" Name=\" " ).append (nameToMatch ).append ('\"' );
239
291
}
240
292
WmiQueryHandler wmiQueryHandler = WmiQueryHandler .createInstance ();
241
- WmiQuery <LogicalDiskProperty > logicalDiskQuery = new WmiQuery <>(wmiClassName .toString (), LogicalDiskProperty .class );
293
+ WmiQuery <LogicalDiskProperty > logicalDiskQuery = new WmiQuery <>(wmiClassName .toString (),
294
+ LogicalDiskProperty .class );
242
295
WmiResult <LogicalDiskProperty > drives = wmiQueryHandler .queryWMI (logicalDiskQuery );
243
296
244
297
for (int i = 0 ; i < drives .getResultCount (); i ++) {
0 commit comments