mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-18 20:39:33 +08:00
* syscalls.cc (try_to_bin): Take additional parameter to get file open
flags. If the file to move to the bin has been opened casesensitive, reopen it caseinsensitive. Explain why. Revert the default name of the Vista-and-later recycler to mixed case for readability. (unlink_nt): Call try_to_bin with file open flags as evaluated.
This commit is contained in:
parent
963addfa27
commit
854ed5f03a
@ -1,3 +1,11 @@
|
||||
2013-11-27 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* syscalls.cc (try_to_bin): Take additional parameter to get file open
|
||||
flags. If the file to move to the bin has been opened casesensitive,
|
||||
reopen it caseinsensitive. Explain why. Revert the default name of
|
||||
the Vista-and-later recycler to mixed case for readability.
|
||||
(unlink_nt): Call try_to_bin with file open flags as evaluated.
|
||||
|
||||
2013-11-26 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* nlsfuncs.cc (wcscoll): Add "__restrict" to definition.
|
||||
|
@ -65,3 +65,7 @@ Bug fixes:
|
||||
|
||||
- dup2() could crash in some cases for a destination >= 256
|
||||
Fixes: http://cygwin.com/ml/cygwin/2013-09/msg00397.html
|
||||
|
||||
- Try to workaround the following problem: unlink(2) could fail, if the
|
||||
file was opened casesensitive and has to be moved to the recycler due
|
||||
to a sharing violation.
|
||||
|
@ -232,7 +232,7 @@ enum bin_status
|
||||
};
|
||||
|
||||
static bin_status
|
||||
try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
|
||||
try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags)
|
||||
{
|
||||
bin_status bin_stat = move_to_bin;
|
||||
NTSTATUS status;
|
||||
@ -268,12 +268,37 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
|
||||
them into the recycler. */
|
||||
if (pfni->FileNameLength == 2) /* root dir. */
|
||||
goto out;
|
||||
/* The recycler name on Vista and later is $Recycler.Bin by default. If the
|
||||
recycler dir disappeared for some reason, the shell32.dll recreates the
|
||||
directory in all upper case. So, we never know beforehand if the dir
|
||||
is written in mixed case or in all upper case. That's a problem when
|
||||
using casesensitivity. If the file handle given to FileRenameInformation
|
||||
has been opened casesensitive, the call also handles the path to the
|
||||
target dir casesensitive. Rather then trying to find the right name
|
||||
of the recycler, we just reopen the file to move with OBJ_CASE_INSENSITIVE,
|
||||
so the subsequent FileRenameInformation works caseinsensitive in terms of
|
||||
the recycler directory name, too. */
|
||||
if (!pc.objcaseinsensitive ())
|
||||
{
|
||||
HANDLE fh_dup;
|
||||
InitializeObjectAttributes (&attr, &ro_u_empty, OBJ_CASE_INSENSITIVE,
|
||||
fh, NULL);
|
||||
status = NtOpenFile (&fh_dup, access, &attr, &io, FILE_SHARE_VALID_FLAGS,
|
||||
flags);
|
||||
if (!NT_SUCCESS (status))
|
||||
debug_printf ("NtOpenFile (reopen) failed, status = %y", status);
|
||||
else
|
||||
{
|
||||
NtClose (fh);
|
||||
fh = fh_dup;
|
||||
}
|
||||
}
|
||||
/* Initialize recycler path. */
|
||||
RtlInitEmptyUnicodeString (&recycler, recyclerbuf, sizeof recyclerbuf);
|
||||
if (!pc.isremote ())
|
||||
{
|
||||
if (wincap.has_recycle_dot_bin ()) /* NTFS and FAT since Vista, ReFS */
|
||||
RtlAppendUnicodeToString (&recycler, L"\\$RECYCLE.BIN\\");
|
||||
RtlAppendUnicodeToString (&recycler, L"\\$Recycle.Bin\\");
|
||||
else if (pc.fs_is_ntfs ()) /* NTFS up to 2K3 */
|
||||
RtlAppendUnicodeToString (&recycler, L"\\RECYCLER\\");
|
||||
else if (pc.fs_is_fat ()) /* FAT up to 2K3 */
|
||||
@ -359,6 +384,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
|
||||
pfri->FileNameLength = recycler.Length;
|
||||
memcpy (pfri->FileName, recycler.Buffer, recycler.Length);
|
||||
frisiz = sizeof *pfri + pfri->FileNameLength - sizeof (WCHAR);
|
||||
|
||||
status = NtSetInformationFile (fh, &io, pfri, frisiz, FileRenameInformation);
|
||||
if (status == STATUS_OBJECT_PATH_NOT_FOUND && !pc.isremote ())
|
||||
{
|
||||
@ -786,7 +812,7 @@ unlink_nt (path_conv &pc)
|
||||
/* Try to move to bin if a sharing violation occured. If that worked,
|
||||
we're done. */
|
||||
if (bin_stat == move_to_bin
|
||||
&& (bin_stat = try_to_bin (pc, fh, access)) >= has_been_moved)
|
||||
&& (bin_stat = try_to_bin (pc, fh, access, flags)) >= has_been_moved)
|
||||
{
|
||||
if (bin_stat == has_been_moved)
|
||||
status = STATUS_SUCCESS;
|
||||
@ -856,7 +882,7 @@ try_again:
|
||||
{
|
||||
debug_printf ("Try-to-bin %S",
|
||||
pc.get_nt_native_path ());
|
||||
bin_stat = try_to_bin (pc, fh, access);
|
||||
bin_stat = try_to_bin (pc, fh, access, flags);
|
||||
}
|
||||
}
|
||||
/* Do NOT handle bin_stat == dir_not_empty here! */
|
||||
@ -916,7 +942,7 @@ try_again:
|
||||
succeeds, we got rid of the file in some way, even if
|
||||
unlinking didn't work. */
|
||||
if (bin_stat == dont_move)
|
||||
bin_stat = try_to_bin (pc, fh, access);
|
||||
bin_stat = try_to_bin (pc, fh, access, flags);
|
||||
if (bin_stat >= has_been_moved)
|
||||
status = bin_stat == has_been_moved
|
||||
? STATUS_SUCCESS
|
||||
|
Loading…
x
Reference in New Issue
Block a user