簡體   English   中英

MSVC2015上的實驗性C ++ 17文件系統:與權限不一致

[英]Experimental C++17 filesystem on MSVC2015: inconsistencies with permissions

我正在嘗試在MSVC2015 (更新1)上使用應該成為C ++ 17(參見技術規范草案N4100 )的實驗性<filesystem>庫。

我可以設法以遞歸方式顯示目錄的完整內容:

    using namespace std::tr2::sys;
    ...
    path dir = canonical(".");
    for (auto& p : recursive_directory_iterator(dir)) {
        if (is_regular_file(p))                
            cout << file_size(p);               
        perms pe = p.status().permissions();  // get authorisations
        cout <<"\t"<< (pe & perms::owner_read ? "r" : "-") // <== error should be allowed
            << (pe & perms::owner_write ? "w" : "-");
        cout <<"\t" << p << endl;     
    }

問題和疑問:

  1. perms對象上的Bitwise & :編譯器抱怨C2440有關從perms到bool的轉換丟失的錯誤 但這應該根據規格允許。 這是一個錯誤還是我錯過了什么?

  2. 我通過轉換pe無符號來解決這個問題。 在那里我注意到,對於每個文件,值都是0xffff ,包括我故意撤回編寫授權的文件。 是否系統地為Windows上的權限返回一個常量虛擬值,或者我忘記了獲得有效權限的內容?

更新 :我在下面談到的關於Windows權限的內容是正確的,但由於某種原因,即使FILE_ATTRIBUTE_READONLY位似乎也沒有起作用。 我會提交一個bug :)

作為現在的解決方法,您可以對生成的路徑記錄執行status() ,例如

#include <filesystem>
#include <iostream>
using namespace std;
using namespace std::tr2::sys;

int main() {
    path dir = canonical(".");
    for (auto& p : recursive_directory_iterator(dir)) {
        if (is_regular_file(p))
            cout << file_size(p);
        file_status stat = status(p); // Workaround bug in MSVC++2015
        perms pe = stat.permissions();  // get authorizations
        cout <<"\t"<< ((pe & perms::owner_read) != perms::none ? "r" : "-")
            << ((pe & perms::owner_write) != perms::none ? "w" : "-");
        cout <<"\t" << p << endl;
    }
}

在我的系統上產生:

PS C:\Users\bion\Desktop\test> ..\fs.exe
68494859        r-      C:\Users\bion\Desktop\test\read-only.mp3
93805063        rw      C:\Users\bion\Desktop\test\read-write.mp3
PS C:\Users\bion\Desktop\test>

perwise對象上的Bitwise&:編譯器抱怨C2440有關從perms到bool的轉換丟失的錯誤。 但這應該根據規格允許。 這是一個錯誤還是我錯過了什么?

Bitwise &通過重載operator&支持operator&並且應該正常工作。 沒有轉換為bool。 如果你想轉換為bool,那么正確的方法是與該enum class聲明的常量進行比較,例如:

if ((permsVar & perms::owner_read) != perms::none)

或者使用該枚舉類的直接初始化實例:

if ((permsVar & perms::owner_read) != perms{})

[bitmask.types]只說:

如果表達式X和Y非零,則在對象X中設置值Y.

並不是你可以用來與enum class進行比較的文字0一些轉換。

我通過轉換pe無符號來解決這個問題。 在那里我注意到,對於每個文件,值都是0xffff,包括我故意撤回編寫授權的文件。 是否系統地為Windows上的權限返回一個常量虛擬值,或者我忘記了獲得有效權限的內容?

Windows的權限模型實際上與Unix權限模型沒有相似之處 - 安全描述符確實具有所有者和組所有者值,但是在Windows DACL之間沒有普遍接受的約定(它可以表達比Unix權限更精細的權限構造)和Unix權限。

因此,目前我們只查找readonly屬性,或者查找一組特定的屬性,如果不是我們“踢”並且說權限未知。 如果你想要便攜,你需要做一些未知的常數。

        // FILE STATUS FUNCTIONS
_FS_DLL _File_type __CLRCALL_PURE_OR_CDECL _Stat(const TCHAR *_Fname, _Perms *_Pmode)
    {   // get file status
    WIN32_FILE_ATTRIBUTE_DATA _Data;

    if (TFUN(GetFileAttributesEx)(_Fname, GetFileExInfoStandard, &_Data))
        {   // get file type and return permissions
        // !!! Here's where we check
        if (_Pmode != 0)
            *_Pmode = _Data.dwFileAttributes & FILE_ATTRIBUTE_READONLY
                ? READONLY_PERMS : perms::all;
        return (_Map_mode(_Data.dwFileAttributes));
        }
    else
        {   // invalid, get error code
        // error mapping code omitted
        }
    }

你期望我們用安全描述符做什么,比如:

O:BAG:SYD:PAI(A;;WD;;;WD)(A;;FA;;;S-1-5-21-2127521184-1604012920-1887927527-9342113)(A;;0x4;;;BA)

其中說:

O:BA :所有者是BUILTIN\\ADMINISTRATORS
G:SY :集團所有者是NT AUTHORITY\\LOCAL SYSTEM 請注意,該組通常不會在Windows權限中使用,並且只是為了與Interix兼容而存在,在這種情況下,Interix是唯一一個讀取或寫入安全描述符的人,因此可以執行任何操作。 :)
D:PAI :DACL是DACL_PROTECTED (不繼承父項的權限)和DACL_AUTO_INHERIT (參與普通權限繼承系統;例如,此文件系統對象的子項將繼承此權限)

  • (A ;; WD ;;; WD) :授予WRITE_DAC (更改安全描述符的DACL部分的權限)訪問WORLD\\EVERYONE 嗯, WRITE_DAC不是讀,寫或執行的,那么我們在那里做什么呢?
  • (A ;; FA ;;; S-1-5-21-2127521184-1604012920-1887927527-9342113) :向REDMOND\\bion bion授予FILE_ALL_ACCESS 請注意,我不是所有者,群組所有者或“其他人”,所以您如何映射這個?
  • (A ;; 0x4 ;;; BA)FILE_APPEND_DATA授予BUILTIN\\ADMINISTRATORS 這有點像寫,但不允許您更改文件中已有的內容...

(而且我遺漏了一些像強制訪問控制......的東西。)

我不是說我們不能嘗試在這種映射上做得更好,但是如果你需要做非常重要的權限工作,那么<filesystem> TS對於支持訪問控制列表的系統無法真正幫助你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM