mirror of https://github.com/python/cpython
gh-102765: Update ntpath.isdir/isfile/islink/exists to use GetFileInformationByName when available (GH-103485)
This commit is contained in:
parent
8a0c7f1e40
commit
b701dce340
|
@ -75,6 +75,24 @@ static inline BOOL _Py_GetFileInformationByName(
|
||||||
return GetFileInformationByName(FileName, FileInformationClass, FileInfoBuffer, FileInfoBufferSize);
|
return GetFileInformationByName(FileName, FileInformationClass, FileInfoBuffer, FileInfoBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline BOOL _Py_GetFileInformationByName_ErrorIsTrustworthy(int error)
|
||||||
|
{
|
||||||
|
switch(error) {
|
||||||
|
case ERROR_FILE_NOT_FOUND:
|
||||||
|
case ERROR_PATH_NOT_FOUND:
|
||||||
|
case ERROR_NOT_READY:
|
||||||
|
case ERROR_BAD_NET_NAME:
|
||||||
|
case ERROR_BAD_NETPATH:
|
||||||
|
case ERROR_BAD_PATHNAME:
|
||||||
|
case ERROR_INVALID_NAME:
|
||||||
|
case ERROR_FILENAME_EXCED_RANGE:
|
||||||
|
return TRUE;
|
||||||
|
case ERROR_NOT_SUPPORTED:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4789,6 +4789,8 @@ os__path_isdir_impl(PyObject *module, PyObject *path)
|
||||||
FILE_BASIC_INFO info;
|
FILE_BASIC_INFO info;
|
||||||
path_t _path = PATH_T_INITIALIZE("isdir", "path", 0, 1);
|
path_t _path = PATH_T_INITIALIZE("isdir", "path", 0, 1);
|
||||||
int result;
|
int result;
|
||||||
|
BOOL slow_path = TRUE;
|
||||||
|
FILE_STAT_BASIC_INFORMATION statInfo;
|
||||||
|
|
||||||
if (!path_converter(path, &_path)) {
|
if (!path_converter(path, &_path)) {
|
||||||
path_cleanup(&_path);
|
path_cleanup(&_path);
|
||||||
|
@ -4800,43 +4802,60 @@ os__path_isdir_impl(PyObject *module, PyObject *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
if (_path.fd != -1) {
|
if (_path.wide) {
|
||||||
hfile = _Py_get_osfhandle_noraise(_path.fd);
|
if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo,
|
||||||
close_file = FALSE;
|
&statInfo, sizeof(statInfo))) {
|
||||||
}
|
if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
|
||||||
else {
|
slow_path = FALSE;
|
||||||
hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL,
|
result = statInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
} else if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||||
}
|
slow_path = FALSE;
|
||||||
if (hfile != INVALID_HANDLE_VALUE) {
|
|
||||||
if (GetFileInformationByHandleEx(hfile, FileBasicInfo, &info,
|
|
||||||
sizeof(info)))
|
|
||||||
{
|
|
||||||
result = info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
if (close_file) {
|
|
||||||
CloseHandle(hfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
STRUCT_STAT st;
|
|
||||||
switch (GetLastError()) {
|
|
||||||
case ERROR_ACCESS_DENIED:
|
|
||||||
case ERROR_SHARING_VIOLATION:
|
|
||||||
case ERROR_CANT_ACCESS_FILE:
|
|
||||||
case ERROR_INVALID_PARAMETER:
|
|
||||||
if (STAT(_path.wide, &st)) {
|
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
else {
|
} else if (_Py_GetFileInformationByName_ErrorIsTrustworthy(GetLastError())) {
|
||||||
result = S_ISDIR(st.st_mode);
|
slow_path = FALSE;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (slow_path) {
|
||||||
|
if (_path.fd != -1) {
|
||||||
|
hfile = _Py_get_osfhandle_noraise(_path.fd);
|
||||||
|
close_file = FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||||
|
}
|
||||||
|
if (hfile != INVALID_HANDLE_VALUE) {
|
||||||
|
if (GetFileInformationByHandleEx(hfile, FileBasicInfo, &info,
|
||||||
|
sizeof(info)))
|
||||||
|
{
|
||||||
|
result = info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
if (close_file) {
|
||||||
|
CloseHandle(hfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
STRUCT_STAT st;
|
||||||
|
switch (GetLastError()) {
|
||||||
|
case ERROR_ACCESS_DENIED:
|
||||||
|
case ERROR_SHARING_VIOLATION:
|
||||||
|
case ERROR_CANT_ACCESS_FILE:
|
||||||
|
case ERROR_INVALID_PARAMETER:
|
||||||
|
if (STAT(_path.wide, &st)) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = S_ISDIR(st.st_mode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = 0;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
@ -4867,6 +4886,8 @@ os__path_isfile_impl(PyObject *module, PyObject *path)
|
||||||
FILE_BASIC_INFO info;
|
FILE_BASIC_INFO info;
|
||||||
path_t _path = PATH_T_INITIALIZE("isfile", "path", 0, 1);
|
path_t _path = PATH_T_INITIALIZE("isfile", "path", 0, 1);
|
||||||
int result;
|
int result;
|
||||||
|
BOOL slow_path = TRUE;
|
||||||
|
FILE_STAT_BASIC_INFORMATION statInfo;
|
||||||
|
|
||||||
if (!path_converter(path, &_path)) {
|
if (!path_converter(path, &_path)) {
|
||||||
path_cleanup(&_path);
|
path_cleanup(&_path);
|
||||||
|
@ -4878,43 +4899,60 @@ os__path_isfile_impl(PyObject *module, PyObject *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
if (_path.fd != -1) {
|
if (_path.wide) {
|
||||||
hfile = _Py_get_osfhandle_noraise(_path.fd);
|
if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo,
|
||||||
close_file = FALSE;
|
&statInfo, sizeof(statInfo))) {
|
||||||
}
|
if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
|
||||||
else {
|
slow_path = FALSE;
|
||||||
hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL,
|
result = !(statInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
} else if (statInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
}
|
slow_path = FALSE;
|
||||||
if (hfile != INVALID_HANDLE_VALUE) {
|
|
||||||
if (GetFileInformationByHandleEx(hfile, FileBasicInfo, &info,
|
|
||||||
sizeof(info)))
|
|
||||||
{
|
|
||||||
result = !(info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
if (close_file) {
|
|
||||||
CloseHandle(hfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
STRUCT_STAT st;
|
|
||||||
switch (GetLastError()) {
|
|
||||||
case ERROR_ACCESS_DENIED:
|
|
||||||
case ERROR_SHARING_VIOLATION:
|
|
||||||
case ERROR_CANT_ACCESS_FILE:
|
|
||||||
case ERROR_INVALID_PARAMETER:
|
|
||||||
if (STAT(_path.wide, &st)) {
|
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
else {
|
} else if (_Py_GetFileInformationByName_ErrorIsTrustworthy(GetLastError())) {
|
||||||
result = S_ISREG(st.st_mode);
|
slow_path = FALSE;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (slow_path) {
|
||||||
|
if (_path.fd != -1) {
|
||||||
|
hfile = _Py_get_osfhandle_noraise(_path.fd);
|
||||||
|
close_file = FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||||
|
}
|
||||||
|
if (hfile != INVALID_HANDLE_VALUE) {
|
||||||
|
if (GetFileInformationByHandleEx(hfile, FileBasicInfo, &info,
|
||||||
|
sizeof(info)))
|
||||||
|
{
|
||||||
|
result = !(info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
if (close_file) {
|
||||||
|
CloseHandle(hfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
STRUCT_STAT st;
|
||||||
|
switch (GetLastError()) {
|
||||||
|
case ERROR_ACCESS_DENIED:
|
||||||
|
case ERROR_SHARING_VIOLATION:
|
||||||
|
case ERROR_CANT_ACCESS_FILE:
|
||||||
|
case ERROR_INVALID_PARAMETER:
|
||||||
|
if (STAT(_path.wide, &st)) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = S_ISREG(st.st_mode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = 0;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
@ -4944,6 +4982,8 @@ os__path_exists_impl(PyObject *module, PyObject *path)
|
||||||
BOOL close_file = TRUE;
|
BOOL close_file = TRUE;
|
||||||
path_t _path = PATH_T_INITIALIZE("exists", "path", 0, 1);
|
path_t _path = PATH_T_INITIALIZE("exists", "path", 0, 1);
|
||||||
int result;
|
int result;
|
||||||
|
BOOL slow_path = TRUE;
|
||||||
|
FILE_STAT_BASIC_INFORMATION statInfo;
|
||||||
|
|
||||||
if (!path_converter(path, &_path)) {
|
if (!path_converter(path, &_path)) {
|
||||||
path_cleanup(&_path);
|
path_cleanup(&_path);
|
||||||
|
@ -4955,36 +4995,50 @@ os__path_exists_impl(PyObject *module, PyObject *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
if (_path.fd != -1) {
|
if (_path.wide) {
|
||||||
hfile = _Py_get_osfhandle_noraise(_path.fd);
|
if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo,
|
||||||
close_file = FALSE;
|
&statInfo, sizeof(statInfo))) {
|
||||||
}
|
if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
|
||||||
else {
|
slow_path = FALSE;
|
||||||
hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL,
|
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
|
||||||
}
|
|
||||||
if (hfile != INVALID_HANDLE_VALUE) {
|
|
||||||
result = 1;
|
|
||||||
if (close_file) {
|
|
||||||
CloseHandle(hfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
STRUCT_STAT st;
|
|
||||||
switch (GetLastError()) {
|
|
||||||
case ERROR_ACCESS_DENIED:
|
|
||||||
case ERROR_SHARING_VIOLATION:
|
|
||||||
case ERROR_CANT_ACCESS_FILE:
|
|
||||||
case ERROR_INVALID_PARAMETER:
|
|
||||||
if (STAT(_path.wide, &st)) {
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
break;
|
} else if (_Py_GetFileInformationByName_ErrorIsTrustworthy(GetLastError())) {
|
||||||
default:
|
slow_path = FALSE;
|
||||||
result = 0;
|
result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (slow_path) {
|
||||||
|
if (_path.fd != -1) {
|
||||||
|
hfile = _Py_get_osfhandle_noraise(_path.fd);
|
||||||
|
close_file = FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||||
|
}
|
||||||
|
if (hfile != INVALID_HANDLE_VALUE) {
|
||||||
|
result = 1;
|
||||||
|
if (close_file) {
|
||||||
|
CloseHandle(hfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
STRUCT_STAT st;
|
||||||
|
switch (GetLastError()) {
|
||||||
|
case ERROR_ACCESS_DENIED:
|
||||||
|
case ERROR_SHARING_VIOLATION:
|
||||||
|
case ERROR_CANT_ACCESS_FILE:
|
||||||
|
case ERROR_INVALID_PARAMETER:
|
||||||
|
if (STAT(_path.wide, &st)) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
@ -5015,6 +5069,8 @@ os__path_islink_impl(PyObject *module, PyObject *path)
|
||||||
FILE_ATTRIBUTE_TAG_INFO info;
|
FILE_ATTRIBUTE_TAG_INFO info;
|
||||||
path_t _path = PATH_T_INITIALIZE("islink", "path", 0, 1);
|
path_t _path = PATH_T_INITIALIZE("islink", "path", 0, 1);
|
||||||
int result;
|
int result;
|
||||||
|
BOOL slow_path = TRUE;
|
||||||
|
FILE_STAT_BASIC_INFORMATION statInfo;
|
||||||
|
|
||||||
if (!path_converter(path, &_path)) {
|
if (!path_converter(path, &_path)) {
|
||||||
path_cleanup(&_path);
|
path_cleanup(&_path);
|
||||||
|
@ -5026,45 +5082,62 @@ os__path_islink_impl(PyObject *module, PyObject *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
if (_path.fd != -1) {
|
if (_path.wide) {
|
||||||
hfile = _Py_get_osfhandle_noraise(_path.fd);
|
if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo,
|
||||||
close_file = FALSE;
|
&statInfo, sizeof(statInfo))) {
|
||||||
}
|
slow_path = FALSE;
|
||||||
else {
|
if (statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||||
hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL,
|
result = (statInfo.ReparseTag == IO_REPARSE_TAG_SYMLINK);
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
if (hfile != INVALID_HANDLE_VALUE) {
|
|
||||||
if (GetFileInformationByHandleEx(hfile, FileAttributeTagInfo, &info,
|
|
||||||
sizeof(info)))
|
|
||||||
{
|
|
||||||
result = (info.ReparseTag == IO_REPARSE_TAG_SYMLINK);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
if (close_file) {
|
|
||||||
CloseHandle(hfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
STRUCT_STAT st;
|
|
||||||
switch (GetLastError()) {
|
|
||||||
case ERROR_ACCESS_DENIED:
|
|
||||||
case ERROR_SHARING_VIOLATION:
|
|
||||||
case ERROR_CANT_ACCESS_FILE:
|
|
||||||
case ERROR_INVALID_PARAMETER:
|
|
||||||
if (LSTAT(_path.wide, &st)) {
|
|
||||||
result = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = S_ISLNK(st.st_mode);
|
result = 0;
|
||||||
|
}
|
||||||
|
} else if (_Py_GetFileInformationByName_ErrorIsTrustworthy(GetLastError())) {
|
||||||
|
slow_path = FALSE;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (slow_path) {
|
||||||
|
if (_path.fd != -1) {
|
||||||
|
hfile = _Py_get_osfhandle_noraise(_path.fd);
|
||||||
|
close_file = FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
if (hfile != INVALID_HANDLE_VALUE) {
|
||||||
|
if (GetFileInformationByHandleEx(hfile, FileAttributeTagInfo, &info,
|
||||||
|
sizeof(info)))
|
||||||
|
{
|
||||||
|
result = (info.ReparseTag == IO_REPARSE_TAG_SYMLINK);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
if (close_file) {
|
||||||
|
CloseHandle(hfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
STRUCT_STAT st;
|
||||||
|
switch (GetLastError()) {
|
||||||
|
case ERROR_ACCESS_DENIED:
|
||||||
|
case ERROR_SHARING_VIOLATION:
|
||||||
|
case ERROR_CANT_ACCESS_FILE:
|
||||||
|
case ERROR_INVALID_PARAMETER:
|
||||||
|
if (LSTAT(_path.wide, &st)) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = S_ISLNK(st.st_mode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = 0;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
Loading…
Reference in New Issue