Handle unlinking in-use files on virtual drives

* path.cc (path_conv::set_nt_native_path): New function.
        * path.h (path_conv::set_nt_native_path): Add prototype.
        * syscall.cc (try_to_bin): Handle moving files to the recycler
        accessed via a local virtual drive (subst).  Fix a problem renaming
        the file to the unique replacement name on Samba.  Align comment.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2015-04-23 15:02:32 +02:00
parent 4e99630cfd
commit 5abb0ed13c
4 changed files with 46 additions and 3 deletions

View File

@ -1,3 +1,11 @@
2015-04-23 Corinna Vinschen <corinna@vinschen.de>
* path.cc (path_conv::set_nt_native_path): New function.
* path.h (path_conv::set_nt_native_path): Add prototype.
* syscall.cc (try_to_bin): Handle moving files to the recycler
accessed via a local virtual drive (subst). Fix a problem renaming
the file to the unique replacement name on Samba. Align comment.
2015-04-22 Corinna Vinschen <corinna@vinschen.de> 2015-04-22 Corinna Vinschen <corinna@vinschen.de>
* fhandler_tty.cc (fhandler_pty_slave::fch_close_handles): Don't close * fhandler_tty.cc (fhandler_pty_slave::fch_close_handles): Don't close

View File

@ -486,6 +486,18 @@ get_nt_native_path (const char *path, UNICODE_STRING& upath, bool dos)
return &upath; return &upath;
} }
/* Handle with extrem care! Only used in a certain instance in try_to_bin.
Every other usage needs a careful check. */
void
path_conv::set_nt_native_path (PUNICODE_STRING new_path)
{
wide_path = (PWCHAR) crealloc_abort (wide_path, new_path->MaximumLength);
memcpy (wide_path, new_path->Buffer, new_path->Length);
uni_path.Length = new_path->Length;
uni_path.MaximumLength = new_path->MaximumLength;
uni_path.Buffer = wide_path;
}
PUNICODE_STRING PUNICODE_STRING
path_conv::get_nt_native_path () path_conv::get_nt_native_path ()
{ {

View File

@ -270,6 +270,7 @@ class path_conv
~path_conv (); ~path_conv ();
inline const char *get_win32 () const { return path; } inline const char *get_win32 () const { return path; }
void set_nt_native_path (PUNICODE_STRING);
PUNICODE_STRING get_nt_native_path (); PUNICODE_STRING get_nt_native_path ();
inline POBJECT_ATTRIBUTES get_object_attr (OBJECT_ATTRIBUTES &attr, inline POBJECT_ATTRIBUTES get_object_attr (OBJECT_ATTRIBUTES &attr,
SECURITY_ATTRIBUTES &sa) SECURITY_ATTRIBUTES &sa)

View File

@ -314,15 +314,35 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags)
RtlAppendUnicodeToString (&recycler, L"\\Recycled\\"); RtlAppendUnicodeToString (&recycler, L"\\Recycled\\");
else else
goto out; goto out;
/* Is the file a subdir of the recycler? */
RtlInitCountedUnicodeString(&fname, pfni->FileName, pfni->FileNameLength); RtlInitCountedUnicodeString(&fname, pfni->FileName, pfni->FileNameLength);
/* Is the file a subdir of the recycler? */
if (RtlEqualUnicodePathPrefix (&fname, &recycler, TRUE)) if (RtlEqualUnicodePathPrefix (&fname, &recycler, TRUE))
goto out; goto out;
/* Is fname the recycler? Temporarily hide trailing backslash. */ /* Is fname the recycler? Temporarily hide trailing backslash. */
recycler.Length -= sizeof (WCHAR); recycler.Length -= sizeof (WCHAR);
if (RtlEqualUnicodeString (&fname, &recycler, TRUE)) if (RtlEqualUnicodeString (&fname, &recycler, TRUE))
goto out; goto out;
/* Is fname really a subcomponent of the full path? If not, there's
a high probability we're acessing the file via a virtual drive
created with "subst". Check and accommodate it. Note that we
ony get here if the virtual drive is really pointing to a local
drive. Otherwise pc.isremote () returns "true". */
if (!RtlEqualUnicodePathSuffix (pc.get_nt_native_path (), &fname, TRUE))
{
WCHAR drive[3] = { pc.get_nt_native_path ()->Buffer[4], ':', '\0' };
PWCHAR tgt = tp.w_get ();
if (QueryDosDeviceW (drive, tgt, NT_MAX_PATH)
&& !wcsncmp (tgt, L"\\??\\", 4))
{
UNICODE_STRING new_path;
wcsncpy (tgt + 6, fname.Buffer, fname.Length / sizeof (WCHAR));
RtlInitCountedUnicodeString(&new_path, tgt,
6 * sizeof (WCHAR) + fname.Length);
pc.set_nt_native_path (&new_path);
}
}
/* Create root dir path from file name information. */ /* Create root dir path from file name information. */
RtlSplitUnicodePath (&fname, &fname, NULL); RtlSplitUnicodePath (&fname, &fname, NULL);
RtlSplitUnicodePath (pc.get_nt_native_path (), &root, NULL); RtlSplitUnicodePath (pc.get_nt_native_path (), &root, NULL);
@ -367,9 +387,11 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags)
starting at U+dc00. Use plain ASCII chars on filesystems not supporting starting at U+dc00. Use plain ASCII chars on filesystems not supporting
Unicode. The rest of the filename is the inode number in hex encoding Unicode. The rest of the filename is the inode number in hex encoding
and a hash of the full NT path in hex. The combination allows to remove and a hash of the full NT path in hex. The combination allows to remove
multiple hardlinks to the same file. */ multiple hardlinks to the same file. Samba doesn't like the transposed
names. */
RtlAppendUnicodeToString (&recycler, RtlAppendUnicodeToString (&recycler,
pc.fs_flags () & FILE_UNICODE_ON_DISK (pc.fs_flags () & FILE_UNICODE_ON_DISK
&& !pc.fs_is_samba ())
? L".\xdc63\xdc79\xdc67" : L".cyg"); ? L".\xdc63\xdc79\xdc67" : L".cyg");
pfii = (PFILE_INTERNAL_INFORMATION) infobuf; pfii = (PFILE_INTERNAL_INFORMATION) infobuf;
/* Note: Modern Samba versions apparently don't like buffer sizes of more /* Note: Modern Samba versions apparently don't like buffer sizes of more