* dtable.cc (dtable::dup_worker): Reset path_conv handle in duplicated
fhandler. * fhandler.cc (fhandler_base::fstatvfs): Keep handle in created path_conv. * fhandler.h (fhandler_base::get_stat_access): New method. (fhandler_base::get_stat_handle): New method. * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Use handle returned by get_stat_handle. Only request inode from system if it isn't already set in the fhandler, and only for filesystems supporting them. (fhandler_base::fstat_fs): Use handle returned by get_stat_handle. Change the way open_fs is called. Explain why. (fhandler_base::fstat_helper): Use handle returned by get_stat_handle. Never use 0 inode number. Simplify executable recognition by re-using get_stat_handle if file could be opened with sufficient rights. (fhandler_disk_file::fstatvfs): Use handle returned by get_stat_handle. (fhandler_disk_file::facl): Use handle returned by get_stat_handle in GETACL and GETACLCNT cases. (fhandler_disk_file::link): Use handle returned by get_stat_handle instead of opening file here again. Add comment. (readdir_get_ino): Keep handle in created path_conv and drop opening file. * ntdll.h (wait_pending): New helper function. * path.cc (symlink_info::check): Drop unused 'opt' parameter from declaration. Add path_conv_handle argument. (path_conv::check): Make sure conv_handle is closed. Keep PC_KEEP_HANDLE flag in pflags_or. Accommodate call to sym.check to new args. (path_conv::~path_conv): Close conv_handle. (symlink_info::check_shortcut): Don't re-open file here, just use incoming handle. Drop goto's and label out. (symlink_info::check_sysfile): Don't re-open file here, just use incoming handle. Keep track of file position to accommodate the fact that file has been opened asynchronously in calling function. (symlink_info::check_nfs_symlink): Don't re-open file here, just use incoming handle. (symlink_info::check): Drop unused 'opt' parameter. Add path_conv_handle argument. Always try to open file with GENERIC_READ rights first to allow reading file content w/o having to re-open the file. Drop back to READ_CONTROL | FILE_READ_ATTRIBUTES otherwise. Call symlink test functions (except for check_reparse_point) only if file could be opened with GENERIC_READ. Keep file handle open if PC_KEEP_HANDLE is set in pflags. * path.h (enum pathconv_arg): Add PC_KEEP_HANDLE flag. (class path_conv_handle): New class. (class path_conv): Add conv_handle member. (path_conv::operator =): Duplicate conv_handle. (path_conv::handle): New method. (path_conv::access): New method. (path_conv::reset_conv_handle): New method. (path_conv::close_conv_handle): New method.
This commit is contained in:
@ -57,6 +57,7 @@ enum pathconv_arg
|
||||
PC_CHECK_EA = 0x0040,
|
||||
PC_POSIX = 0x0080,
|
||||
PC_NOWARN = 0x0100,
|
||||
PC_KEEP_HANDLE = 0x00400000,
|
||||
PC_NO_ACCESS_CHECK = 0x00800000
|
||||
};
|
||||
|
||||
@ -86,6 +87,33 @@ enum path_types
|
||||
PATH_SOCKET = 0x40000000
|
||||
};
|
||||
|
||||
class path_conv_handle
|
||||
{
|
||||
HANDLE hdl;
|
||||
ACCESS_MASK acc;
|
||||
public:
|
||||
path_conv_handle () : hdl (NULL), acc (0) {}
|
||||
inline void set (HANDLE h, ACCESS_MASK a) { hdl = h; acc = a; }
|
||||
inline void close ()
|
||||
{
|
||||
if (hdl)
|
||||
CloseHandle (hdl);
|
||||
set (NULL, 0);
|
||||
}
|
||||
inline void dup (path_conv_handle &pch)
|
||||
{
|
||||
if (!DuplicateHandle (GetCurrentProcess (), pch.handle (),
|
||||
GetCurrentProcess (), &hdl,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
hdl = NULL;
|
||||
acc = 0;
|
||||
}
|
||||
}
|
||||
inline HANDLE handle () const { return hdl; }
|
||||
inline ACCESS_MASK access () const { return acc; }
|
||||
};
|
||||
|
||||
class symlink_info;
|
||||
|
||||
class path_conv
|
||||
@ -98,6 +126,7 @@ class path_conv
|
||||
void add_ext_from_sym (symlink_info&);
|
||||
DWORD symlink_length;
|
||||
const char *path;
|
||||
path_conv_handle conv_handle;
|
||||
public:
|
||||
unsigned path_flags;
|
||||
const char *known_suffix;
|
||||
@ -220,6 +249,7 @@ class path_conv
|
||||
{
|
||||
memcpy (this, &pc, sizeof pc);
|
||||
path = cstrdup (pc.path);
|
||||
conv_handle.dup (pc.conv_handle);
|
||||
normalized_path = cstrdup(pc.normalized_path);
|
||||
wide_path = NULL;
|
||||
return *this;
|
||||
@ -250,6 +280,11 @@ class path_conv
|
||||
}
|
||||
bool is_binary ();
|
||||
|
||||
HANDLE handle () const { return conv_handle.handle (); }
|
||||
ACCESS_MASK access () const { return conv_handle.access (); }
|
||||
void reset_conv_handle () { conv_handle.set (NULL, 0); }
|
||||
void close_conv_handle () { conv_handle.close (); }
|
||||
|
||||
__ino64_t get_ino_by_handle (HANDLE h);
|
||||
#if 0 /* obsolete, method still exists in fhandler_disk_file.cc */
|
||||
unsigned __stdcall ndisk_links (DWORD);
|
||||
|
Reference in New Issue
Block a user