1.10.1
This commit is contained in:
parent
dc5a2013c8
commit
372cf04a52
|
@ -30,6 +30,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- fixed Remove Sandbox only deletes the contents of the sandbox when an application is running in the sandbox [#3118](https://github.com/sandboxie-plus/Sandboxie/issues/3118)
|
||||
- fixed crash issue with not peroeprly termianted script engine [#3120](https://github.com/sandboxie-plus/Sandboxie/issues/3120)
|
||||
- fixed ImDisk under Sandboxie supervision causes SBIE2337 and sometimes BSoD [#1092)(https://github.com/sandboxie-plus/Sandboxie/issues/1092)
|
||||
- fixed Snapshots don't merge duplicate directory junctions [#3016](https://github.com/sandboxie-plus/Sandboxie/issues/3016)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -189,6 +189,10 @@ static NTSTATUS File_MigrateFile(
|
|||
const WCHAR *TruePath, const WCHAR *CopyPath,
|
||||
BOOLEAN IsWritePath, BOOLEAN WithContents);
|
||||
|
||||
static NTSTATUS File_MigrateJunction(
|
||||
const WCHAR *TruePath, const WCHAR *CopyPath,
|
||||
BOOLEAN IsWritePath);
|
||||
|
||||
static NTSTATUS File_CopyShortName(
|
||||
const WCHAR *TruePath, const WCHAR *CopyPath);
|
||||
|
||||
|
@ -3382,7 +3386,12 @@ ReparseLoop:
|
|||
// write access, or else it would have been handled earlier already)
|
||||
//
|
||||
|
||||
if (CreateDisposition == FILE_OPEN ||
|
||||
if (FileType & TYPE_REPARSE_POINT) {
|
||||
|
||||
status = File_MigrateJunction(
|
||||
TruePath, CopyPath, IsWritePath);
|
||||
|
||||
} else if (CreateDisposition == FILE_OPEN ||
|
||||
CreateDisposition == FILE_OPEN_IF ||
|
||||
TruePathColon) {
|
||||
|
||||
|
|
|
@ -466,3 +466,112 @@ _FX NTSTATUS File_MigrateFile(
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// File_MigrateJunction
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS File_MigrateJunction(
|
||||
const WCHAR* TruePath, const WCHAR* CopyPath,
|
||||
BOOLEAN IsWritePath)
|
||||
{
|
||||
NTSTATUS status;
|
||||
HANDLE TrueHandle, CopyHandle;
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING objname;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
FILE_NETWORK_OPEN_INFORMATION open_info;
|
||||
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, Secure_NormalSD);
|
||||
|
||||
//
|
||||
// open TruePath. if we get a sharing violation trying to open it,
|
||||
// try to get the driver to open it bypassing share access. if even
|
||||
// this fails, then we can't copy the data, but can still create an
|
||||
// empty file
|
||||
//
|
||||
|
||||
RtlInitUnicodeString(&objname, TruePath);
|
||||
|
||||
status = __sys_NtCreateFile(
|
||||
&TrueHandle, FILE_GENERIC_READ, &objattrs, &IoStatusBlock,
|
||||
NULL, 0, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN, FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
|
||||
|
||||
/*if (IsWritePath && status == STATUS_ACCESS_DENIED)
|
||||
status = STATUS_SHARING_VIOLATION;
|
||||
|
||||
if (status == STATUS_SHARING_VIOLATION) {
|
||||
|
||||
status = SbieApi_OpenFile(&TrueHandle, TruePath);
|
||||
}*/
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
//
|
||||
// query attributes and size of the TruePath file
|
||||
//
|
||||
|
||||
status = __sys_NtQueryInformationFile(
|
||||
TrueHandle, &IoStatusBlock, &open_info,
|
||||
sizeof(FILE_NETWORK_OPEN_INFORMATION), FileNetworkOpenInformation);
|
||||
|
||||
//
|
||||
// Get the reparse point data from the source
|
||||
//
|
||||
|
||||
BYTE buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; // We need a large buffer
|
||||
REPARSE_DATA_BUFFER* reparseDataBuffer = (REPARSE_DATA_BUFFER*)buf;
|
||||
status = __sys_NtFsControlFile(TrueHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_GET_REPARSE_POINT, NULL, 0, reparseDataBuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
//
|
||||
// Create the destination file with reparse point data
|
||||
//
|
||||
|
||||
RtlInitUnicodeString(&objname, CopyPath);
|
||||
|
||||
status = __sys_NtCreateFile(
|
||||
&CopyHandle, FILE_GENERIC_WRITE, &objattrs, &IoStatusBlock,
|
||||
NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT,
|
||||
NULL, 0);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
//
|
||||
// Set the reparse point data to the destination
|
||||
//
|
||||
|
||||
#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
|
||||
status = __sys_NtFsControlFile(CopyHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_SET_REPARSE_POINT, reparseDataBuffer, REPARSE_MOUNTPOINT_HEADER_SIZE + reparseDataBuffer->ReparseDataLength, NULL, 0);
|
||||
|
||||
//
|
||||
// set information on the CopyPath file
|
||||
//
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
FILE_BASIC_INFORMATION info;
|
||||
|
||||
info.CreationTime.QuadPart = open_info.CreationTime.QuadPart;
|
||||
info.LastAccessTime.QuadPart = open_info.LastAccessTime.QuadPart;
|
||||
info.LastWriteTime.QuadPart = open_info.LastWriteTime.QuadPart;
|
||||
info.ChangeTime.QuadPart = open_info.ChangeTime.QuadPart;
|
||||
info.FileAttributes = open_info.FileAttributes;
|
||||
|
||||
status = File_SetAttributes(CopyHandle, CopyPath, &info);
|
||||
}
|
||||
|
||||
NtClose(TrueHandle);
|
||||
NtClose(CopyHandle);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -98,6 +98,34 @@ NTSTATUS NtIo_RemoveJunction(POBJECT_ATTRIBUTES objattrs)
|
|||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS NtIo_DeleteFolderRecursivelyImpl(POBJECT_ATTRIBUTES objattrs, bool (*cb)(const WCHAR* info, void* param), void* param);
|
||||
|
||||
NTSTATUS NtIo_DeleteFileImpl(ULONG FileAttributes, OBJECT_ATTRIBUTES* attr, bool (*cb)(const WCHAR* info, void* param), void* param)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
if (FileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
|
||||
NtIo_RemoveProblematicAttributes(attr);
|
||||
|
||||
if (FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
status = NtIo_RemoveJunction(attr);
|
||||
else if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
status = NtIo_DeleteFolderRecursivelyImpl(attr, cb, param);
|
||||
|
||||
if (NT_SUCCESS(status))
|
||||
status = NtDeleteFile(attr);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS NtIo_DeleteFileImpl(SNtObject& ntObject, bool (*cb)(const WCHAR* info, void* param), void* param)
|
||||
{
|
||||
FILE_BASIC_INFORMATION info = { 0 };
|
||||
NtQueryAttributesFile(&ntObject.attr, &info);
|
||||
|
||||
return NtIo_DeleteFileImpl(info.FileAttributes, &ntObject.attr, cb, param);
|
||||
}
|
||||
|
||||
NTSTATUS NtIo_DeleteFolderRecursivelyImpl(POBJECT_ATTRIBUTES objattrs, bool (*cb)(const WCHAR* info, void* param), void* param)
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
@ -147,16 +175,7 @@ NTSTATUS NtIo_DeleteFolderRecursivelyImpl(POBJECT_ATTRIBUTES objattrs, bool (*cb
|
|||
|
||||
SNtObject ntFoundObject(FileName, Handle);
|
||||
|
||||
if (FileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
|
||||
NtIo_RemoveProblematicAttributes(&ntFoundObject.attr);
|
||||
|
||||
if (FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
status = NtIo_RemoveJunction(&ntFoundObject.attr);
|
||||
else if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
status = NtIo_DeleteFolderRecursivelyImpl(&ntFoundObject.attr, cb, param);
|
||||
|
||||
if (NT_SUCCESS(status))
|
||||
status = NtDeleteFile(&ntFoundObject.attr);
|
||||
status = NtIo_DeleteFileImpl(FileAttributes, &ntFoundObject.attr, cb, param);
|
||||
}
|
||||
|
||||
NtClose(Handle);
|
||||
|
@ -255,7 +274,7 @@ BOOLEAN NtIo_FileExists(POBJECT_ATTRIBUTES objattrs)
|
|||
IO_STATUS_BLOCK Iosb;
|
||||
|
||||
HANDLE handle;
|
||||
status = NtCreateFile(&handle, SYNCHRONIZE, objattrs, &Iosb, NULL, 0, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
|
||||
status = NtCreateFile(&handle, SYNCHRONIZE, objattrs, &Iosb, NULL, 0, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT, NULL, 0);
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
// STATUS_OBJECT_NAME_NOT_FOUND // STATUS_OBJECT_PATH_NOT_FOUND
|
||||
|
@ -325,11 +344,15 @@ NTSTATUS NtIo_MergeFolder(POBJECT_ATTRIBUTES src_objattrs, POBJECT_ATTRIBUTES de
|
|||
//if (FileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
|
||||
// NtIo_RemoveProblematicAttributes(&ntFoundObject.attr);
|
||||
|
||||
if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if (FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
if (FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
if (TargetExists)
|
||||
status = NtIo_DeleteFileImpl(ntDestObject, cb, param);
|
||||
if (NT_SUCCESS(status))
|
||||
status = NtIo_RenameJunction(&ntSrcObject.attr, dest_objattrs, FileName.c_str());
|
||||
else if (TargetExists)
|
||||
}
|
||||
else if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if (TargetExists)
|
||||
status = NtIo_MergeFolder(&ntSrcObject.attr, &ntDestObject.attr, cb, param);
|
||||
else
|
||||
status = NtIo_RenameFolder(&ntSrcObject.attr, dest_objattrs, FileName.c_str());
|
||||
|
@ -337,7 +360,7 @@ NTSTATUS NtIo_MergeFolder(POBJECT_ATTRIBUTES src_objattrs, POBJECT_ATTRIBUTES de
|
|||
else
|
||||
{
|
||||
if (TargetExists)
|
||||
status = NtDeleteFile(&ntDestObject.attr);
|
||||
status = NtIo_DeleteFileImpl(ntDestObject, cb, param);
|
||||
if (NT_SUCCESS(status))
|
||||
status = NtIo_RenameFile(&ntSrcObject.attr, dest_objattrs, FileName.c_str());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue