WinAPI确定文件是否可访问/私有的方法

WinAPI way to determine if a file is accessible/private

本文关键字:方法 访问 文件 是否 WinAPI      更新时间:2023-10-16

win32c++;是否有一种方法来确定一个文件夹/文件是可访问的?你知道如果你试图访问C:/Windows目录下的某个文件夹&你会得到一个弹出框,提示"此文件夹不可访问"。

也许有一个文件属性常数表示文件是私有的?比如FILE_ATTRIBUTE_PRIVATE?

WIN32_FIND_DATA dirData;
while (FindNextFile( dir, &dirData ) != 0 )
{
    // I made the following constant up
    if ( !(fileData.dwFileAttributes & FILE_ATTRIBUTE_PRIVATE) )
    {
        // file is accessible so store filepath
        files.push_back( fileData.cFileName );
    }
    else // file is not accessible so dont store
}

Or是知道的唯一方法:

dir = FindFirstFileEx( (LPCTSTR)directory.c_str(), FindExInfoStandard, &dirData, FindExSearchNameMatch, NULL, 0 );
if ( dir == ??? ) { the file is inaccessible } [/code]

最好的办法就是试着访问它。

您可以计算访问控制列表对特定用户帐户授予的访问权限,但这非常复杂,并且在进行访问检查后权限可能会更改。所以只要打开文件并处理拒绝访问错误。

它不会是文件本身的标志,因为不同的帐户可以访问不同的文件/目录。相反,windows使用ACL(访问控制列表),这是一种数据结构,决定谁可以访问什么。

windows中的acl可以用于句柄引用的任何东西(文件、目录、进程、互斥锁、命名管道…)。您可以通过进入文件属性并查看"安全"选项卡查看文件acl。

所以在你的应用程序中,你真的不想检查一个标志,而是比较文件的ACL与你的应用程序运行的用户帐户。查看AccessCheck Win32功能。我想这正是你要找的。

就我个人而言,我从来没有使用过这个函数,但如果你正在寻找Win32解决方案,你想要一个函数调用,这可能是你最好的选择。然而,正如其他人指出的那样,这可能太复杂了。我一直使用_access(或_waccess),这是CRT的一部分,非常容易使用,并且您不会因为获取文件句柄而只关闭它而影响性能(取决于您的循环有多紧密,这些调用实际上可以加起来)。

int _access( 
   const char *path, 
   int mode 
);

使用简单:

http://msdn.microsoft.com/en-us/library/1w06ktdy%28v=vs.80%29.aspx

是的,Aaron Ballman你是老板!哦,天哪!我可以用一些有用的脏话来表达我现在的喜悦。

https://blog.aaronballman.com/2011/08/how-to-check-access-rights/是一个在win32中检查fpath上的访问权限的示例链接。以及文档不完善的AccessCheck win32函数背后的解释。代码如下:

bool canAccessPath( LPCTSTR folderName, DWORD genericAccessRights )
{
    bool bRet = 0;
    DWORD length = 0;
    if (!::GetFileSecurity( folderName, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &length ) &&
            ERROR_INSUFFICIENT_BUFFER == ::GetLastError())
    {
        PSECURITY_DESCRIPTOR security = static_cast< PSECURITY_DESCRIPTOR >( ::malloc( length ) );
        if (security && ::GetFileSecurity( folderName, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, security, length, &length ))
        {
            HANDLE hToken = NULL;
            if (::OpenProcessToken( ::GetCurrentProcess(), TOKEN_IMPERSONATE|TOKEN_QUERY|TOKEN_DUPLICATE|STANDARD_RIGHTS_READ, &hToken ))
            {
                HANDLE hImpersonatedToken = NULL;
                if (::DuplicateToken( hToken, SecurityImpersonation, &hImpersonatedToken ))
                {
                    GENERIC_MAPPING mapping = { 0xFFFFFFFF };
                    PRIVILEGE_SET privileges = { 0 };
                    DWORD grantedAccess = 0, privilegesLength = sizeof( privileges );
                    BOOL result = FALSE;
                    mapping.GenericRead = FILE_GENERIC_READ;
                    mapping.GenericWrite = FILE_GENERIC_WRITE;
                    mapping.GenericExecute = FILE_GENERIC_EXECUTE;
                    mapping.GenericAll = FILE_ALL_ACCESS;
                    ::MapGenericMask( &genericAccessRights, &mapping );
                    if (::AccessCheck( security, hImpersonatedToken, genericAccessRights,
                            &mapping, &privileges, &privilegesLength, &grantedAccess, &result ))
                    {
                     bRet = result == TRUE;
                    }
                    ::CloseHandle( hImpersonatedToken );
                }
                ::CloseHandle( hToken );
            }
            ::free( security );
        }
    }
    return bRet;
}

不要害羞,去他的网站看看他的作品吧。我相信他有更多有趣的东西。