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