如何检查目录符号链接的目标是否存在?

时间:2019-03-26 02:22:27

标签: windows winapi visual-c++ filesystems symlink

我正在开发针对Windows XP的Windows应用程序。

我的应用程序需要解析到文件和文件夹的符号链接。要检查目标是否存在,我可以使用CreateFile来指向文件的符号链接。但是在搜索了整整一天的Google和MSDN之后,我发现如果需要获取目录的句柄,则需要使用标志FILE_FLAG_BACKUP_SEMANTICS。这需要我的应用程序请求更高的特权。我知道许多用户对此行为不满意,因此我需要找到另一种方法来检查目录符号链接的目标是否存在。

我也读过Symbolic Link Effects on File Systems Functions。我可以用来测试文件或目录是否存在的其他功能都检查符号链接本身,而不是其目标。我尝试了一些功能,例如_access_s。他们还只检查符号链接本身。

所以我的问题是,是否有任何方法可以在不需要更高特权的情况下检查目录符号链接的目标是否存在。

1 个答案:

答案 0 :(得分:2)

  

我可以对符号文件使用CreateFile来获取文件句柄并   然后检查文件是否存在。

如果在调用FILE_FLAG_OPEN_REPARSE_POINT中未指定CreateFile,并且您获得文件句柄,则意味着存在符号链接/安装点目标。因此已经不需要检查任何东西。如果由于目标不存在而导致调用失败,则最后一个错误将是ERROR_FILE_NOT_FOUNDERROR_PATH_NOT_FOUND(也可能是ERROR_BAD_PATHNAME

关于FILE_FLAG_BACKUP_SEMANTICS-这是CreateFile API的非常糟糕的设计。此api内部调用NtCreateFileFILE_FLAG_BACKUP_SEMANTICS映射到FILE_OPEN_FOR_BACKUP_INTENT CreateOptions 标志。此标志在IopCheckBackupRestorePrivilege

内部检查
  

此功能将确定呼叫者是否要求任何访问   可以通过“备份”或“还原”权限来满足,如果可以,   执行特权检查。如果特权检查成功,则   相应的位将从RemainingDesiredAccess中移出   字段在AccessState结构中并放入   以前的GrantedAccess字段。

     

请注意,如果呼叫者没有一个或两个特权,则不会拒绝访问,因为可以通过以下方式授予他所需的访问权限:   对象上的安全描述符。

因此,即使呼叫者没有“备份”或“还原”权限中的一个或两个,这也不会造成问题。

但是NtCreateFile有接下来的2个选项:FILE_DIRECTORY_FILEFILE_NON_DIRECTORY_FILE-我们指定要创建/打开文件还是目录。如果我们(潜在)创建新项目-我们需要指定是要创建目录(必须设置FILE_DIRECTORY_FILE还是不创建目录(FILE_NON_DIRECTORY_FILE,但是默认情况下是这种情况-可选)。当我们打开文件时-这两个标志都是可选的-如果我们都没有指定-这意味着我们不在乎是打开文件还是目录。如果我们对此很在意-请指定此标志之一。

但是如果看CreateFile可见不存在的选项,则显式映射到FILE_DIRECTORY_FILEFILE_NON_DIRECTORY_FILECreateFile用于此.. FILE_FLAG_BACKUP_SEMANTICS选项。从我的角度来看,这是不合逻辑的,但实际上是这样。如果未设置FILE_FLAG_BACKUP_SEMANTICSCreateFile会为FILE_NON_DIRECTORY_FILE传递NtCreateFile选项。设置时-通过FILE_OPEN_FOR_BACKUP_INTENT不通过 FILE_NON_DIRECTORY_FILE。这使您可以打开文件或目录。并且没有设置集FILE_DIRECTORY_FILE的选项-因为此CreatrFile无法创建新目录。

因此,FILE_DIRECTORY_FILEFILE_NON_DIRECTORY_FILE可以有单独的选择,CreateFile滥用FILE_FLAG_BACKUP_SEMANTICS在这里具有双重意义