This commit is contained in:
parent
9dec3f6f97
commit
604961a02f
|
@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- fixed Cannot run explorer.exe on emulate admin sandbox [#3516](https://github.com/sandboxie-plus/Sandboxie/issues/3516)
|
||||
- fixed potential BSOD issue with WFP when trace loging is enabled
|
||||
- fixed Run from Sandbox > Run > Program and Run from folder doesn't use the same working dir [#3555](https://github.com/sandboxie-plus/Sandboxie/issues/3555)
|
||||
- fixed UseNewSymlinkResolver causes applications to create both the link and the target folder [#3481](https://github.com/sandboxie-plus/Sandboxie/issues/3481)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -917,6 +917,82 @@ _FX NTSTATUS File_GetFileName(HANDLE FileHandle, ULONG NameLen, WCHAR* NameBuf)
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// File_OpenForAddTempLink
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS File_OpenForAddTempLink(HANDLE* handle, WCHAR *path, ULONG CreateOptions)
|
||||
{
|
||||
NTSTATUS status;
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING objname;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
P_NtCreateFile pNtCreateFile = __sys_NtCreateFile;
|
||||
// special case for File_InitRecoverFolders as its called bfore we hook those functions
|
||||
if (! pNtCreateFile)
|
||||
pNtCreateFile = NtCreateFile;
|
||||
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
//
|
||||
// first try the copy path
|
||||
//
|
||||
|
||||
if (_wcsnicmp(path, Dll_BoxFilePath, Dll_BoxFilePathLen) != 0)
|
||||
{
|
||||
WCHAR* CopyPath = NULL;
|
||||
|
||||
THREAD_DATA* TlsData = Dll_GetTlsData(NULL);
|
||||
|
||||
Dll_PushTlsNameBuffer(TlsData);
|
||||
|
||||
File_GetCopyPath(path, &CopyPath);
|
||||
|
||||
//
|
||||
// get template file if present, and reparse the path
|
||||
//
|
||||
|
||||
WCHAR* TmplName = File_FindSnapshotPath(CopyPath);
|
||||
if (TmplName != NULL)
|
||||
RtlInitUnicodeString(&objname, TmplName);
|
||||
else
|
||||
RtlInitUnicodeString(&objname, CopyPath);
|
||||
|
||||
status = pNtCreateFile(
|
||||
handle, FILE_GENERIC_READ | SYNCHRONIZE, &objattrs,
|
||||
&IoStatusBlock, NULL, 0, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN, CreateOptions,
|
||||
NULL, 0);
|
||||
|
||||
Dll_PopTlsNameBuffer(TlsData);
|
||||
|
||||
}
|
||||
else // its already a copy path
|
||||
status = STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// then try the true path
|
||||
//
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
|
||||
RtlInitUnicodeString(&objname, path);
|
||||
|
||||
status = pNtCreateFile(
|
||||
handle, FILE_GENERIC_READ | SYNCHRONIZE, &objattrs,
|
||||
&IoStatusBlock, NULL, 0, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN,
|
||||
CreateOptions,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// File_AddTempLink
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -926,113 +1002,37 @@ _FX FILE_LINK *File_AddTempLink(WCHAR *path)
|
|||
{
|
||||
NTSTATUS status;
|
||||
HANDLE handle;
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING objname;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
FILE_LINK *link;
|
||||
WCHAR *newpath;
|
||||
BOOLEAN stop;
|
||||
BOOLEAN bPermLinkPath = FALSE;
|
||||
WCHAR* CopyPath = NULL;
|
||||
|
||||
//
|
||||
// try to open the path
|
||||
//
|
||||
|
||||
P_NtCreateFile pNtCreateFile = __sys_NtCreateFile;
|
||||
P_NtClose pNtClose = __sys_NtClose;
|
||||
P_NtFsControlFile pNtFsControlFile = __sys_NtFsControlFile;
|
||||
// special case for File_InitRecoverFolders as its called bfore we hook those functions
|
||||
if (! pNtCreateFile)
|
||||
pNtCreateFile = NtCreateFile;
|
||||
if (! pNtClose)
|
||||
pNtClose = NtClose;
|
||||
if (! pNtFsControlFile)
|
||||
pNtFsControlFile = NtFsControlFile;
|
||||
|
||||
stop = TRUE;
|
||||
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
newpath = NULL;
|
||||
|
||||
BOOLEAN UserReparse = SbieApi_QueryConfBool(NULL, L"UseNewSymlinkResolver", TRUE);
|
||||
|
||||
if (UserReparse) {
|
||||
|
||||
//
|
||||
// first try the copy path
|
||||
//
|
||||
status = File_OpenForAddTempLink(&handle, path, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT);
|
||||
|
||||
if (_wcsnicmp(path, Dll_BoxFilePath, Dll_BoxFilePathLen) != 0)
|
||||
{
|
||||
THREAD_DATA* TlsData = Dll_GetTlsData(NULL);
|
||||
|
||||
Dll_PushTlsNameBuffer(TlsData);
|
||||
|
||||
File_GetCopyPath(path, &CopyPath);
|
||||
|
||||
//
|
||||
// get template file if present, and reparse the path
|
||||
//
|
||||
|
||||
WCHAR* TmplName = File_FindSnapshotPath(CopyPath);
|
||||
if (TmplName != NULL)
|
||||
RtlInitUnicodeString(&objname, TmplName);
|
||||
else
|
||||
RtlInitUnicodeString(&objname, CopyPath);
|
||||
|
||||
status = pNtCreateFile(
|
||||
&handle, FILE_GENERIC_READ | SYNCHRONIZE, &objattrs,
|
||||
&IoStatusBlock, NULL, 0, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT,
|
||||
NULL, 0);
|
||||
|
||||
Dll_PopTlsNameBuffer(TlsData);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
CopyPath = NULL;
|
||||
}
|
||||
else // its already a copy path
|
||||
status = STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// then try the true path
|
||||
//
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
|
||||
RtlInitUnicodeString(&objname, path);
|
||||
|
||||
status = pNtCreateFile(
|
||||
&handle, FILE_GENERIC_READ | SYNCHRONIZE, &objattrs,
|
||||
&IoStatusBlock, NULL, 0, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT,
|
||||
NULL, 0);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
UserReparse = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UserReparse) {
|
||||
|
||||
RtlInitUnicodeString(&objname, path);
|
||||
|
||||
status = pNtCreateFile(
|
||||
&handle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &objattrs,
|
||||
&IoStatusBlock, NULL, 0, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
if (UserReparse) {
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
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);
|
||||
|
||||
newpath = NULL;
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
|
@ -1053,133 +1053,139 @@ _FX FILE_LINK *File_AddTempLink(WCHAR *path)
|
|||
SubstituteNameBuffer[reparseDataBuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
|
||||
if (SubstituteNameBuffer && !RelativePath) // todo RelativePath - for now we fall back to UserReparse = FALSE;
|
||||
if (SubstituteNameBuffer)
|
||||
{
|
||||
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 (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) {
|
||||
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);
|
||||
while (input_len > 0 && input_str[input_len - 1] == L'\\')
|
||||
input_len -= 1; // remove trailing backslash
|
||||
|
||||
newpath = File_TranslateTempLinks_2(input_str, input_len);
|
||||
newpath = File_TranslateTempLinks_2(input_str, input_len);
|
||||
|
||||
if (input_str != SubstituteNameBuffer)
|
||||
Dll_Free(input_str);
|
||||
if (input_str != SubstituteNameBuffer)
|
||||
Dll_Free(input_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*THREAD_DATA* TlsData = Dll_GetTlsData(NULL);
|
||||
|
||||
Dll_PushTlsNameBuffer(TlsData);
|
||||
|
||||
WCHAR* TruePath = NULL;
|
||||
if (NT_SUCCESS(File_GetTruePath(newpath, &TruePath))) {
|
||||
|
||||
Dll_Free(newpath);
|
||||
newpath = Dll_AllocTemp((wcslen(TruePath) + 1) * sizeof(WCHAR));
|
||||
wcscpy(newpath, TruePath);
|
||||
}
|
||||
|
||||
Dll_PopTlsNameBuffer(TlsData);*/
|
||||
}
|
||||
//else if (status == STATUS_NOT_A_REPARSE_POINT)
|
||||
|
||||
if (!newpath) {
|
||||
|
||||
if (CopyPath) {
|
||||
newpath = Dll_AllocTemp((wcslen(path) + 1) * sizeof(WCHAR));
|
||||
wcscpy(newpath, path);
|
||||
} else
|
||||
UserReparse = FALSE;
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
Dll_Free(reparseDataBuffer);
|
||||
|
||||
pNtClose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
const ULONG PATH_BUF_LEN = 1024;
|
||||
|
||||
//
|
||||
// get the reparsed absolute path
|
||||
//
|
||||
if (!newpath) {
|
||||
|
||||
const ULONG PATH_BUF_LEN = 1024;
|
||||
|
||||
if (!UserReparse) {
|
||||
|
||||
newpath = Dll_AllocTemp(PATH_BUF_LEN);
|
||||
|
||||
status = File_GetFileName(handle, PATH_BUF_LEN - 4, newpath);
|
||||
}
|
||||
status = File_OpenForAddTempLink(&handle, path, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
//
|
||||
// make sure path does not contain duplicate backslashes
|
||||
// get the reparsed absolute path
|
||||
//
|
||||
|
||||
ULONG len = wcslen(newpath);
|
||||
WCHAR *name = newpath;
|
||||
while (name[0]) {
|
||||
if (name[0] == L'\\' && name[1] == L'\\') {
|
||||
ULONG move_len = len - (ULONG)(name - newpath) + 1;
|
||||
wmemmove(name, name + 1, move_len);
|
||||
--len;
|
||||
} else
|
||||
++name;
|
||||
newpath = Dll_AllocTemp(PATH_BUF_LEN);
|
||||
|
||||
status = File_GetFileName(handle, PATH_BUF_LEN - 4, newpath);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
Dll_Free(newpath);
|
||||
newpath = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// convert permanent links (i.e. drive mount points)
|
||||
//
|
||||
pNtClose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
len = File_FixPermLinksForTempLink(
|
||||
newpath, len, (PATH_BUF_LEN - 4) / sizeof(WCHAR));
|
||||
if (newpath) {
|
||||
|
||||
//
|
||||
// verify the link points to a local drive
|
||||
//
|
||||
//
|
||||
// check if what we got is a copy path and convert it to a true path
|
||||
//
|
||||
|
||||
if (File_FindPermLinksForMatchPath(newpath, len))
|
||||
{
|
||||
// release lock by File_FindPermLinksForMatchPath
|
||||
LeaveCriticalSection(File_DrivesAndLinks_CritSec);
|
||||
bPermLinkPath = TRUE;
|
||||
}
|
||||
THREAD_DATA* TlsData = Dll_GetTlsData(NULL);
|
||||
|
||||
if (! FILE_IS_REDIRECTOR_OR_MUP(newpath, len) && !bPermLinkPath) {
|
||||
const FILE_DRIVE *drive = File_GetDriveForPath(newpath, len);
|
||||
const FILE_GUID *guid = NULL;
|
||||
if(!drive)
|
||||
guid = File_GetGuidForPath(newpath, len);
|
||||
if (drive || guid) {
|
||||
LeaveCriticalSection(File_DrivesAndLinks_CritSec);
|
||||
stop = FALSE;
|
||||
}
|
||||
}
|
||||
Dll_PushTlsNameBuffer(TlsData);
|
||||
|
||||
WCHAR* TruePath = NULL;
|
||||
if (NT_SUCCESS(File_GetTruePath(newpath, &TruePath))) {
|
||||
|
||||
} else {
|
||||
Dll_Free(newpath);
|
||||
newpath = NULL;
|
||||
newpath = Dll_AllocTemp((wcslen(TruePath) + 1) * sizeof(WCHAR));
|
||||
wcscpy(newpath, TruePath);
|
||||
}
|
||||
|
||||
pNtClose(handle);
|
||||
Dll_PopTlsNameBuffer(TlsData);
|
||||
|
||||
//
|
||||
// make sure path does not contain duplicate backslashes
|
||||
//
|
||||
|
||||
ULONG len = wcslen(newpath);
|
||||
WCHAR *name = newpath;
|
||||
while (name[0]) {
|
||||
if (name[0] == L'\\' && name[1] == L'\\') {
|
||||
ULONG move_len = len - (ULONG)(name - newpath) + 1;
|
||||
wmemmove(name, name + 1, move_len);
|
||||
--len;
|
||||
} else
|
||||
++name;
|
||||
}
|
||||
|
||||
//
|
||||
// convert permanent links (i.e. drive mount points)
|
||||
//
|
||||
|
||||
len = File_FixPermLinksForTempLink(
|
||||
newpath, len, (PATH_BUF_LEN - 4) / sizeof(WCHAR));
|
||||
|
||||
//
|
||||
// verify the link points to a local drive
|
||||
//
|
||||
|
||||
if (File_FindPermLinksForMatchPath(newpath, len))
|
||||
{
|
||||
// release lock by File_FindPermLinksForMatchPath
|
||||
LeaveCriticalSection(File_DrivesAndLinks_CritSec);
|
||||
bPermLinkPath = TRUE;
|
||||
}
|
||||
|
||||
if (! FILE_IS_REDIRECTOR_OR_MUP(newpath, len) && !bPermLinkPath) {
|
||||
const FILE_DRIVE *drive = File_GetDriveForPath(newpath, len);
|
||||
const FILE_GUID *guid = NULL;
|
||||
if(!drive)
|
||||
guid = File_GetGuidForPath(newpath, len);
|
||||
if (drive || guid) {
|
||||
LeaveCriticalSection(File_DrivesAndLinks_CritSec);
|
||||
stop = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
newpath = NULL;
|
||||
newpath = path;
|
||||
|
||||
//
|
||||
// add the new link and return
|
||||
//
|
||||
|
||||
if (! newpath)
|
||||
newpath = path;
|
||||
|
||||
if (File_AddLink(FALSE, path, newpath)) {
|
||||
link = List_Head(File_TempLinks);
|
||||
if (link)
|
||||
|
|
Loading…
Reference in New Issue