This commit is contained in:
DavidXanatos 2024-02-25 16:27:25 +01:00
parent 50331bc7d8
commit 5b2cf70e4f
4 changed files with 82 additions and 59 deletions

View File

@ -17,6 +17,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed ### Changed
- changed DynData format to add flags - changed DynData format to add flags
- Revert or provide a way to opt out of the new sandbox directory structure for volumes without drive letters [#3632](https://github.com/sandboxie-plus/Sandboxie/issues/3632)
- guid usage can be re-enabled with "UseVolumeGuidWhenNoLetter=y"
### Removed
- removed UseNewSymlinkResolver setting new mechanism is always used

View File

@ -363,9 +363,9 @@ static WCHAR *File_PublicUser = NULL;
static ULONG File_PublicUserLen = 0; static ULONG File_PublicUserLen = 0;
static BOOLEAN File_DriveAddSN = FALSE; static BOOLEAN File_DriveAddSN = FALSE;
static BOOLEAN File_UseVolumeGuid = FALSE;
BOOLEAN File_Delete_v2 = FALSE; BOOLEAN File_Delete_v2 = FALSE;
static BOOLEAN File_NoReparse = FALSE;
static WCHAR *File_AltBoxPath = NULL; static WCHAR *File_AltBoxPath = NULL;
static ULONG File_AltBoxPathLen = 0; static ULONG File_AltBoxPathLen = 0;
@ -572,13 +572,13 @@ _FX NTSTATUS File_GetCopyPathImpl(WCHAR* TruePath, WCHAR **OutCopyPath, ULONG *O
ULONG drive_len; ULONG drive_len;
guid = NULL;
drive = File_GetDriveForPath(TruePath, length); drive = File_GetDriveForPath(TruePath, length);
if (drive) if (drive)
drive_len = drive->len; drive_len = drive->len;
else else
drive = File_GetDriveForUncPath(TruePath, length, &drive_len); drive = File_GetDriveForUncPath(TruePath, length, &drive_len);
if (!drive && File_UseVolumeGuid)
if (!drive)
guid = File_GetGuidForPath(TruePath, length); guid = File_GetGuidForPath(TruePath, length);
if (drive || guid) { if (drive || guid) {
@ -763,9 +763,8 @@ check_sandbox_prefix:
drive = NULL; drive = NULL;
guid = NULL; guid = NULL;
if (name[_DriveLen - 1] == L'\\') { if (name[_DriveLen - 1] == L'\\') {
if (name[_DriveLen] == L'{') if (name[_DriveLen] == L'{' && File_UseVolumeGuid)
guid = File_GetLinkForGuid(&name[_DriveLen]); guid = File_GetLinkForGuid(&name[_DriveLen]);
else else
drive = File_GetDriveForLetter(name[_DriveLen]); drive = File_GetDriveForLetter(name[_DriveLen]);
@ -1131,8 +1130,10 @@ _FX NTSTATUS File_GetName(
// the next section of code from trying to translate symlinks // the next section of code from trying to translate symlinks
// //
drive = File_GetDriveForPath(objname_buf, objname_len / sizeof(WCHAR)); guid = NULL;
if(!drive) drive = File_GetDriveForPath(
objname_buf, objname_len / sizeof(WCHAR));
if(!drive && File_UseVolumeGuid)
guid = File_GetGuidForPath(objname_buf, objname_len / sizeof(WCHAR)); guid = File_GetGuidForPath(objname_buf, objname_len / sizeof(WCHAR));
if (drive || guid) { if (drive || guid) {

View File

@ -144,7 +144,7 @@ _FX BOOLEAN File_Init(void)
File_DriveAddSN = SbieApi_QueryConfBool(NULL, L"UseVolumeSerialNumbers", FALSE); File_DriveAddSN = SbieApi_QueryConfBool(NULL, L"UseVolumeSerialNumbers", FALSE);
File_NoReparse = SbieApi_QueryConfBool(NULL, L"NoPathReparse", FALSE); File_UseVolumeGuid = SbieApi_QueryConfBool(NULL, L"UseVolumeGuidWhenNoLetter", FALSE);
if (! File_InitDrives(0xFFFFFFFF)) if (! File_InitDrives(0xFFFFFFFF))
return FALSE; return FALSE;
@ -878,6 +878,25 @@ _FX void File_InitLinks(THREAD_DATA *TlsData)
DosPath += wcslen(DosPath) + 1; DosPath += wcslen(DosPath) + 1;
} }
} else if (File_UseVolumeGuid) {
// handle the case where the volume is not mounted as a
// drive letter:
// add reparse points for all mounted directories
//
// This behavioure creates \[BoxRoot]\drive\{guid} fodlers
// instead of using the first mount point on a volume with a letter
//
WCHAR *FirstDosPath = DosPath;
File_AddLink(TRUE, FirstDosPath, DeviceName);
DosPath += DosPathLen + 1;
while (*DosPath) {
File_AddLink(TRUE, DosPath, DeviceName);
DosPath += wcslen(DosPath) + 1;
}
} else { } else {
// //
@ -889,11 +908,17 @@ _FX void File_InitLinks(THREAD_DATA *TlsData)
// also to the first mounted directory // also to the first mounted directory
// //
//
// Note: this behavioure makes the first mounted directory
// the location in the box where all files for that volume will be located
// other mount points will be redirected to this folder
//
WCHAR *FirstDosPath = DosPath; WCHAR *FirstDosPath = DosPath;
File_AddLink(TRUE, FirstDosPath, DeviceName); File_AddLink(TRUE, DeviceName, FirstDosPath);
DosPath += DosPathLen + 1; DosPath += DosPathLen + 1;
while (*DosPath) { while (*DosPath) {
File_AddLink(TRUE, DosPath, DeviceName); File_AddLink(TRUE, DosPath, FirstDosPath);
DosPath += wcslen(DosPath) + 1; DosPath += wcslen(DosPath) + 1;
} }
} }

View File

@ -604,9 +604,6 @@ _FX WCHAR *File_TranslateTempLinks(
WCHAR *ret; WCHAR *ret;
ULONG TruePath_len, ret_len; ULONG TruePath_len, ret_len;
if (File_NoReparse)
return NULL;
// //
// entry // entry
// //
@ -1022,72 +1019,67 @@ _FX FILE_LINK *File_AddTempLink(WCHAR *path)
stop = TRUE; stop = TRUE;
newpath = NULL; newpath = NULL;
status = File_OpenForAddTempLink(&handle, path, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT);
BOOLEAN UserReparse = SbieApi_QueryConfBool(NULL, L"UseNewSymlinkResolver", TRUE); if (NT_SUCCESS(status)) {
if (UserReparse) { REPARSE_DATA_BUFFER* reparseDataBuffer = Dll_AllocTemp(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
status = pNtFsControlFile(handle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_GET_REPARSE_POINT, NULL, 0, reparseDataBuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
status = File_OpenForAddTempLink(&handle, path, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT);
if (NT_SUCCESS(status)) { if (NT_SUCCESS(status)) {
REPARSE_DATA_BUFFER* reparseDataBuffer = Dll_AllocTemp(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); WCHAR* SubstituteNameBuffer = NULL;
status = pNtFsControlFile(handle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_GET_REPARSE_POINT, NULL, 0, reparseDataBuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); //WCHAR* PrintNameBuffer = NULL;
BOOL RelativePath = FALSE;
if (NT_SUCCESS(status)) { if (reparseDataBuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK)
{
SubstituteNameBuffer = &reparseDataBuffer->SymbolicLinkReparseBuffer.PathBuffer[reparseDataBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
if (reparseDataBuffer->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE)
RelativePath = TRUE;
SubstituteNameBuffer[reparseDataBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR)] = 0;
}
else if (reparseDataBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
{
SubstituteNameBuffer = &reparseDataBuffer->MountPointReparseBuffer.PathBuffer[reparseDataBuffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
SubstituteNameBuffer[reparseDataBuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR)] = 0;
}
WCHAR* SubstituteNameBuffer = NULL; if (SubstituteNameBuffer)
//WCHAR* PrintNameBuffer = NULL; {
BOOL RelativePath = FALSE; if (RelativePath)
if (reparseDataBuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK)
{ {
SubstituteNameBuffer = &reparseDataBuffer->SymbolicLinkReparseBuffer.PathBuffer[reparseDataBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)]; // todo RelativePath - for now we fall back to the old method
if (reparseDataBuffer->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE)
RelativePath = TRUE;
SubstituteNameBuffer[reparseDataBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR)] = 0;
} }
else if (reparseDataBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) else
{ {
SubstituteNameBuffer = &reparseDataBuffer->MountPointReparseBuffer.PathBuffer[reparseDataBuffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)]; WCHAR* input_str = SubstituteNameBuffer;
SubstituteNameBuffer[reparseDataBuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR)] = 0; if (_wcsnicmp(input_str, L"\\??\\Volume{", 11) == 0)
} input_str = File_TranslateGuidToNtPath(SubstituteNameBuffer);
else if (_wcsnicmp(input_str, File_BQQB, 4) == 0)
input_str = File_TranslateDosToNtPath(SubstituteNameBuffer + 4);
if (SubstituteNameBuffer) if (input_str) {
{
if (RelativePath)
{
// todo RelativePath - for now we fall back to the old method
}
else
{
WCHAR* input_str = SubstituteNameBuffer;
if (_wcsnicmp(input_str, L"\\??\\Volume{", 11) == 0)
input_str = File_TranslateGuidToNtPath(SubstituteNameBuffer);
else if (_wcsnicmp(input_str, File_BQQB, 4) == 0)
input_str = File_TranslateDosToNtPath(SubstituteNameBuffer + 4);
if (input_str) { ULONG input_len = wcslen(input_str);
while (input_len > 0 && input_str[input_len - 1] == L'\\')
input_len -= 1; // remove trailing backslash
ULONG input_len = wcslen(input_str); newpath = File_TranslateTempLinks_2(input_str, input_len);
while (input_len > 0 && input_str[input_len - 1] == L'\\')
input_len -= 1; // remove trailing backslash
newpath = File_TranslateTempLinks_2(input_str, input_len); if (input_str != SubstituteNameBuffer)
Dll_Free(input_str);
if (input_str != SubstituteNameBuffer)
Dll_Free(input_str);
}
} }
} }
} }
//else if (status == STATUS_NOT_A_REPARSE_POINT) }
//else if (status == STATUS_NOT_A_REPARSE_POINT)
Dll_Free(reparseDataBuffer); Dll_Free(reparseDataBuffer);
pNtClose(handle); pNtClose(handle);
}
} }
const ULONG PATH_BUF_LEN = 1024; const ULONG PATH_BUF_LEN = 1024;