zzy
zzy

Reputation: 1793

How to check whether the target of a directory symbolic link exists?

I'm developing a Windows application that targets Windows XP.

My app needs to resolve symbolic links to files and folders. To check whether the target exists, I can use CreateFile for symbolic links to files. But after I searched Google and MSDN for a whole day, I found that if I need to get the handle of a directory, I need to use the flag FILE_FLAG_BACKUP_SEMANTICS. This requires my application to request higher privileges. I know many users are not happy with this behavior, so I need to find another way to check whether the target of a directory symbolic link exists.

I have also read Symbolic Link Effects on File Systems Functions. The other functions I can use to test for the existence of a file or directory all check the symbolic link itself, not its target. I have tried some functions like _access_s. They also only check the symbolic link itself.

So my question is whether there is any way to check whether the target of a directory symbolic link exists without requiring higher privileges.

Upvotes: 2

Views: 1421

Answers (1)

RbMm
RbMm

Reputation: 33706

I could use CreateFile for symbolic file to get the file handle and then check the file is exist or not.

If FILE_FLAG_OPEN_REPARSE_POINT is not specified in call CreateFile and you get file handle this mean that symbolic link/mount point target is exist. so already not need check something. if call fail because target not exist last error will be ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND (may be also ERROR_BAD_PATHNAME)

about FILE_FLAG_BACKUP_SEMANTICS - this is very bad design of CreateFile api. this api internal call NtCreateFile. the FILE_FLAG_BACKUP_SEMANTICS mapped to FILE_OPEN_FOR_BACKUP_INTENT CreateOptions flag. this flag checked inside IopCheckBackupRestorePrivilege

This function will determine if the caller is asking for any accesses that may be satisfied by Backup or Restore privileges, and if so, perform the privilege checks. If the privilege checks succeed, then the appropriate bits will be moved out of the RemainingDesiredAccess field in the AccessState structure and placed into the PreviouslyGrantedAccess field.

Note that access is not denied if the caller does not have either or both of the privileges, since he may be granted the desired access via the security descriptor on the object.

so even if caller have not either or both of the Backup or Restore privileges this not create problems.

but NtCreateFile have the next 2 options: FILE_DIRECTORY_FILE and FILE_NON_DIRECTORY_FILE - this let specify are we want create/open file or directory. if we (potential) create new item - we need specify are we want create directory (FILE_DIRECTORY_FILE must be set) or not directory (FILE_NON_DIRECTORY_FILE, but by default assume this case - so optional). when we open file - both this flags is optional - if we not specify both - this mean that we not care are we open file or directory. if we care about this - need specify one of this flags.

but if look to CreateFile visible that not exist option which explicity mapped to FILE_DIRECTORY_FILE or FILE_NON_DIRECTORY_FILE. the CreateFile use for this .. FILE_FLAG_BACKUP_SEMANTICS option. this is very not logical from my view, but as is. when FILE_FLAG_BACKUP_SEMANTICS not set CreateFile pass FILE_NON_DIRECTORY_FILE option for NtCreateFile. when it set - pass FILE_OPEN_FOR_BACKUP_INTENT and not pass FILE_NON_DIRECTORY_FILE. this allow you open file or directory. and no option for set FILE_DIRECTORY_FILE - because this CreatrFile can not create new directory.

so instead have separate option for FILE_DIRECTORY_FILE and FILE_NON_DIRECTORY_FILE, CreateFile abuse FILE_FLAG_BACKUP_SEMANTICS wich have double sense here

Upvotes: 2

Related Questions