But apparently, GetFileAttributes()
can succeed even if it is passed
an invalid path.
this is wrong. if path really invalid - GetFileAttributes
return appropriate error (ERROR_INVALID_NAME
or ERROR_FILE_NOT_FOUND
usually). not also that need check for ERROR_SHARING_VIOLATION
and ERROR_ACCESS_DENIED
in case GetFileAttributes
return INVALID_FILE_ATTRIBUTES
. because win32 convert to ERROR_ACCESS_DENIED
not only STATUS_ACCESS_DENIED
but many other unrelated status - more correct use NtQueryAttributesFile
. also exist undocumented
extern "C" NTSYSAPI BOOLEAN NTAPI RtlDoesFileExists_U( _In_ PWSTR FileName );
which do this job (internal it call NtQueryAttributesFile
and check also for STATUS_SHARING_VIOLATION
AND STATUS_ACCESS_DENIED
)
also after api return - file already can be deleted (or created) - as result returned value can be already wrong. so usual if we need some file/folder - need not try check but create or open it. or get error in this operation
but really your problem not in GetFileAttributes
but in win32 to nt path conversion.
you assume that path D:/test../../../../../../..
is wrong. but system think that not. the RtlDosPathNameToNtPathName_U_WithStatus
(or related) used by system for convert win32 path to nt. if test this api with your path, this give:
UNICODE_STRING us;
if (0 <= RtlDosPathNameToNtPathName_U_WithStatus(L"D:/test../../../../../../..", &us, 0, 0))
{
DbgPrint("%wZ\n", &us);
RtlFreeUnicodeString(&us);
}
if (0 <= RtlDosPathNameToNtPathName_U_WithStatus(L"../../../../../../..", &us, 0, 0))
{
DbgPrint("%wZ\n", &us);
RtlFreeUnicodeString(&us);
}
\??\D:\
and \??\<X>:\
so system convert this to root folder on drive. and this folder exist.