@@ -1162,11 +1162,272 @@ impl FilePermissions {
11621162
11631163 pub fn set_readonly ( & mut self , readonly : bool ) {
11641164 if readonly {
1165- self . attrs |= c:: FILE_ATTRIBUTE_READONLY ;
1165+ // According to SetFileAttributes, any other values
1166+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1167+ if self . normal ( ) {
1168+ self . attrs = c:: FILE_ATTRIBUTE_READONLY ;
1169+ } else {
1170+ self . attrs |= c:: FILE_ATTRIBUTE_READONLY ;
1171+ }
11661172 } else {
11671173 self . attrs &= !c:: FILE_ATTRIBUTE_READONLY ;
11681174 }
11691175 }
1176+
1177+ fn hidden ( & self ) -> bool {
1178+ self . attrs & c:: FILE_ATTRIBUTE_HIDDEN != 0
1179+ }
1180+
1181+ fn set_hidden ( & mut self , hidden : bool ) {
1182+ if hidden {
1183+ // According to SetFileAttributes, any other values
1184+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1185+ if self . normal ( ) {
1186+ self . attrs = c:: FILE_ATTRIBUTE_HIDDEN ;
1187+ } else {
1188+ self . attrs |= c:: FILE_ATTRIBUTE_HIDDEN ;
1189+ }
1190+ } else {
1191+ self . attrs &= !c:: FILE_ATTRIBUTE_HIDDEN ;
1192+ }
1193+ }
1194+
1195+ fn system ( & self ) -> bool {
1196+ self . attrs & c:: FILE_ATTRIBUTE_SYSTEM != 0
1197+ }
1198+
1199+ fn set_system ( & mut self , system : bool ) {
1200+ if system {
1201+ // According to SetFileAttributes, any other values
1202+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1203+ if self . normal ( ) {
1204+ self . attrs = c:: FILE_ATTRIBUTE_SYSTEM ;
1205+ } else {
1206+ self . attrs |= c:: FILE_ATTRIBUTE_SYSTEM ;
1207+ }
1208+ } else {
1209+ self . attrs &= !c:: FILE_ATTRIBUTE_SYSTEM ;
1210+ }
1211+ }
1212+
1213+ fn archive ( & self ) -> bool {
1214+ self . attrs & c:: FILE_ATTRIBUTE_ARCHIVE != 0
1215+ }
1216+
1217+ fn set_archive ( & mut self , archive : bool ) {
1218+ if archive {
1219+ // According to SetFileAttributes, any other values
1220+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1221+ if self . normal ( ) {
1222+ self . attrs = c:: FILE_ATTRIBUTE_ARCHIVE ;
1223+ } else {
1224+ self . attrs |= c:: FILE_ATTRIBUTE_ARCHIVE ;
1225+ }
1226+ } else {
1227+ self . attrs &= !c:: FILE_ATTRIBUTE_ARCHIVE ;
1228+ }
1229+ }
1230+
1231+ // This file attribute is only valid when used alone
1232+ // There should be no other file attribute set.
1233+ fn normal ( & self ) -> bool {
1234+ self . attrs == c:: FILE_ATTRIBUTE_NORMAL
1235+ }
1236+
1237+ // According to Microsoft docs here:
1238+ // https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
1239+ // This file attribute is valid only when used alone.
1240+ // The SetFileAttributes seems to recognize this as a
1241+ // reset/zero out flag.
1242+ fn set_normal ( & mut self , normal : bool ) {
1243+ if normal {
1244+ self . attrs = c:: FILE_ATTRIBUTE_NORMAL ;
1245+ }
1246+ }
1247+
1248+ fn temporary ( & self ) -> bool {
1249+ self . attrs & c:: FILE_ATTRIBUTE_TEMPORARY != 0
1250+ }
1251+
1252+ fn set_temporary ( & mut self , temporary : bool ) {
1253+ if temporary {
1254+ // According to SetFileAttributes, any other values
1255+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1256+ if self . normal ( ) {
1257+ self . attrs = c:: FILE_ATTRIBUTE_TEMPORARY ;
1258+ } else {
1259+ self . attrs |= c:: FILE_ATTRIBUTE_TEMPORARY ;
1260+ }
1261+ } else {
1262+ self . attrs &= !c:: FILE_ATTRIBUTE_TEMPORARY ;
1263+ }
1264+ }
1265+
1266+ fn offline ( & self ) -> bool {
1267+ self . attrs & c:: FILE_ATTRIBUTE_OFFLINE != 0
1268+ }
1269+
1270+ fn set_offline ( & mut self , offline : bool ) {
1271+ if offline {
1272+ // According to SetFileAttributes, any other values
1273+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1274+ if self . normal ( ) {
1275+ self . attrs = c:: FILE_ATTRIBUTE_OFFLINE ;
1276+ } else {
1277+ self . attrs |= c:: FILE_ATTRIBUTE_OFFLINE ;
1278+ }
1279+ } else {
1280+ self . attrs &= !c:: FILE_ATTRIBUTE_OFFLINE ;
1281+ }
1282+ }
1283+
1284+ fn not_content_indexed ( & self ) -> bool {
1285+ self . attrs & c:: FILE_ATTRIBUTE_OFFLINE != 0
1286+ }
1287+
1288+ fn set_not_content_indexed ( & mut self , not_content_indexed : bool ) {
1289+ if not_content_indexed {
1290+ // According to SetFileAttributes, any other values
1291+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1292+ if self . normal ( ) {
1293+ self . attrs = c:: FILE_ATTRIBUTE_NOT_CONTENT_INDEXED ;
1294+ } else {
1295+ self . attrs |= c:: FILE_ATTRIBUTE_NOT_CONTENT_INDEXED ;
1296+ }
1297+ } else {
1298+ self . attrs &= !c:: FILE_ATTRIBUTE_NOT_CONTENT_INDEXED ;
1299+ }
1300+ }
1301+
1302+ // This flag is not supported until Windows 8 and Windows Server 2012
1303+ // (not supported on Windows Server 2008 R2, Windows 7, Windows Server 2008,
1304+ // Windows Vista, Windows Server 2003 and Windows XP)
1305+ fn integrity_stream ( & self ) -> bool {
1306+ self . attrs & c:: FILE_ATTRIBUTE_INTEGRITY_STREAM != 0
1307+ }
1308+
1309+ // This flag is not supported until Windows 8 and Windows Server 2012
1310+ // (not supported on Windows Server 2008 R2, Windows 7, Windows Server 2008,
1311+ // Windows Vista, Windows Server 2003 and Windows XP)
1312+ fn set_integrity_stream ( & mut self , integrity_stream : bool ) {
1313+ if integrity_stream {
1314+ // According to SetFileAttributes, any other values
1315+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1316+ if self . normal ( ) {
1317+ self . attrs = c:: FILE_ATTRIBUTE_INTEGRITY_STREAM ;
1318+ } else {
1319+ self . attrs |= c:: FILE_ATTRIBUTE_INTEGRITY_STREAM ;
1320+ }
1321+ } else {
1322+ self . attrs &= !c:: FILE_ATTRIBUTE_INTEGRITY_STREAM ;
1323+ }
1324+ }
1325+
1326+ // This flag is not supported until Windows 8 and Windows Server 2012
1327+ // (not supported on Windows Server 2008 R2, Windows 7, Windows Server 2008,
1328+ // Windows Vista, Windows Server 2003 and Windows XP)
1329+ fn no_scrub_data ( & self ) -> bool {
1330+ self . attrs & c:: FILE_ATTRIBUTE_NO_SCRUB_DATA != 0
1331+ }
1332+
1333+ // This flag is not supported until Windows 8 and Windows Server 2012
1334+ // (not supported on Windows Server 2008 R2, Windows 7, Windows Server 2008,
1335+ // Windows Vista, Windows Server 2003 and Windows XP)
1336+ fn set_no_scrub_data ( & self , no_scrub_data : bool ) {
1337+ if integrity_stream {
1338+ // According to SetFileAttributes, any other values
1339+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1340+ if self . normal ( ) {
1341+ self . attrs = c:: FILE_ATTRIBUTE_NO_SCRUB_DATA ;
1342+ } else {
1343+ self . attrs |= c:: FILE_ATTRIBUTE_NO_SCRUB_DATA ;
1344+ }
1345+ } else {
1346+ self . attrs &= !c:: FILE_ATTRIBUTE_NO_SCRUB_DATA ;
1347+ }
1348+ }
1349+
1350+ // This flag was introduced in Windows 10, version 1703
1351+ fn pinned ( & self ) -> bool {
1352+ self . attrs & c:: FILE_ATTRIBUTE_PINNED != 0
1353+ }
1354+
1355+ // This flag was introduced in Windows 10, version 1703
1356+ fn set_pinned ( & mut self , pinned : bool ) {
1357+ if pinned {
1358+ // According to SetFileAttributes, any other values
1359+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1360+ if self . normal ( ) {
1361+ self . attrs = c:: FILE_ATTRIBUTE_PINNED ;
1362+ } else {
1363+ self . attrs |= c:: FILE_ATTRIBUTE_PINNED ;
1364+ }
1365+ } else {
1366+ self . attrs &= !c:: FILE_ATTRIBUTE_PINNED ;
1367+ }
1368+ }
1369+
1370+ // This flag was introduced in Windows 10, version 1703
1371+ fn unpinned ( & self ) -> bool {
1372+ self . attrs & c:: FILE_ATTRIBUTE_UNPINNED != 0
1373+ }
1374+
1375+ // This flag was introduced in Windows 10, version 1703
1376+ fn set_unpinned ( & mut self , unpinned : bool ) {
1377+ if unpinned {
1378+ // According to SetFileAttributes, any other values
1379+ // passed to this should override FILE_ATTRIBUTE_NORMAL
1380+ if self . normal ( ) {
1381+ self . attrs = c:: FILE_ATTRIBUTE_UNPINNED ;
1382+ } else {
1383+ self . attrs |= c:: FILE_ATTRIBUTE_UNPINNED ;
1384+ }
1385+ } else {
1386+ self . attrs &= !c:: FILE_ATTRIBUTE_UNPINNED ;
1387+ }
1388+ }
1389+
1390+ // We don't have a FILE_ATTRIBUTE_STRICTLY_SEQUENTIAL (aka "SMR Blob")
1391+ // flag yet in `std/src/sys/pal/windows/c/windows_sys.rs`
1392+ // This is a flag that is settable by `attrib` command on Windows
1393+ // Note that this attribute was introduced in Windows 10, version unsure
1394+ // Also see
1395+ // - http://justsolve.archiveteam.org/wiki/DOS/Windows_file_attributes
1396+ // - https://superuser.com/questions/44812/windows-explorers-file-attribute-column-values
1397+ // fn strictly_sequential(&self) -> bool {
1398+ // self.attrs & c::FILE_ATTRIBUTE_STRICTLY_SEQUENTIAL != 0
1399+ // }
1400+
1401+ // fn set_strictly_sequential(&mut self, pinned: bool) {
1402+ // if pinned {
1403+ // // According to SetFileAttributes, any other values
1404+ // // passed to this should override FILE_ATTRIBUTE_NORMAL
1405+ // if self.normal() {
1406+ // self.attrs = c::FILE_ATTRIBUTE_STRICTLY_SEQUENTIAL;
1407+ // } else {
1408+ // self.attrs |= c::FILE_ATTRIBUTE_STRICTLY_SEQUENTIAL;
1409+ // }
1410+ // } else {
1411+ // self.attrs &= !c::FILE_ATTRIBUTE_STRICTLY_SEQUENTIAL;
1412+ // }
1413+ // }
1414+
1415+ // No set_recall_on_data_access because that's settable only by the
1416+ // OS (e.g. OneDrive filter driver)
1417+ // No encrypted, compressed, device, etc. setter attributes because
1418+ // reasons mentioned here: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfileattributesa
1419+ // However, should we have methods that sees if these attributes
1420+ // are set?
1421+
1422+ pub fn file_attributes ( & self ) -> u32 {
1423+ self . attrs as u32
1424+ }
1425+ }
1426+
1427+ impl FromInner < u32 > for FilePermissions {
1428+ fn from_inner ( attr : u32 ) -> FilePermissions {
1429+ FilePermissions { attr }
1430+ }
11701431}
11711432
11721433impl FileTimes {
0 commit comments