зеркало из
1
0
Форкнуть 0
MSIX-PackageSupportFramework/FileRedirectionShim/MoveFileShim.cpp

75 строки
3.5 KiB
C++

//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "FunctionImplementations.h"
#include "PathRedirection.h"
template <typename CharT>
BOOL __stdcall MoveFileShim(_In_ const CharT* existingFileName, _In_ const CharT* newFileName) noexcept
{
auto guard = g_reentrancyGuard.enter();
try
{
if (guard)
{
// NOTE: MoveFile needs delete access to the existing file, but since we won't have delete access to the
// file if it is in the package, we copy-on-read it here. This is slightly wasteful since we're
// copying it only for it to immediately get deleted, but that's simpler than trying to roll our own
// implementation of MoveFile. And of course, the same limitation for deleting files applies here as
// well. Additionally, we don't copy-on-read the destination file for the same reason we don't do the
// same for CopyFile: we give the application the benefit of the doubt that they previously tried to
// delete the file if it exists in the package path.
auto [redirectExisting, existingRedirectPath] = ShouldRedirect(existingFileName, redirect_flags::copy_on_read);
auto [redirectDest, destRedirectPath] = ShouldRedirect(newFileName, redirect_flags::ensure_directory_structure);
if (redirectExisting || redirectDest)
{
return impl::MoveFile(
redirectExisting ? existingRedirectPath.c_str() : widen_argument(existingFileName).c_str(),
redirectDest ? destRedirectPath.c_str() : widen_argument(newFileName).c_str());
}
}
}
catch (...)
{
// Fall back to assuming no redirection is necessary
}
return impl::MoveFile(existingFileName, newFileName);
}
DECLARE_STRING_SHIM(impl::MoveFile, MoveFileShim);
template <typename CharT>
BOOL __stdcall MoveFileExShim(
_In_ const CharT* existingFileName,
_In_opt_ const CharT* newFileName,
_In_ DWORD flags) noexcept
{
auto guard = g_reentrancyGuard.enter();
try
{
if (guard)
{
// See note in MoveFile for commentary on copy-on-read functionality (though we could do better by checking
// flags for MOVEFILE_REPLACE_EXISTING)
auto [redirectExisting, existingRedirectPath] = ShouldRedirect(existingFileName, redirect_flags::copy_on_read);
auto [redirectDest, destRedirectPath] = ShouldRedirect(newFileName, redirect_flags::ensure_directory_structure);
if (redirectExisting || redirectDest)
{
return impl::MoveFileEx(
redirectExisting ? existingRedirectPath.c_str() : widen_argument(existingFileName).c_str(),
redirectDest ? destRedirectPath.c_str() : widen_argument(newFileName).c_str(),
flags);
}
}
}
catch (...)
{
// Fall back to assuming no redirection is necessary
}
return impl::MoveFileEx(existingFileName, newFileName, flags);
}
DECLARE_STRING_SHIM(impl::MoveFileEx, MoveFileExShim);