1.10.1
This commit is contained in:
parent
4a37716882
commit
9680b3f11c
|
@ -11,6 +11,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
### Fixed
|
||||
- fixed "Disable Security Isolation" causes a game to stop playing audio [#2893](https://github.com/sandboxie-plus/Sandboxie/issues/2893)
|
||||
- fixed NtQueryDirectoryObject not implemented [#2734](https://github.com/sandboxie-plus/Sandboxie/issues/2734)
|
||||
|
||||
### Changed
|
||||
- reworked Nt Object Handle handling
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -506,7 +506,7 @@ BOOLEAN File_IsBlockedNetParam(const WCHAR *BoxName);
|
|||
|
||||
void File_GetSetDeviceMap(WCHAR *DeviceMap96);
|
||||
|
||||
void File_NotifyRecover(HANDLE FileHandle);
|
||||
void File_NotifyRecover(HANDLE FileHandle, void* CloseParams);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Functions (key)
|
||||
|
@ -520,7 +520,7 @@ NTSTATUS Key_MarkDeletedAndClose(HANDLE KeyHandle);
|
|||
|
||||
void Key_DiscardMergeByPath(const WCHAR *TruePath, BOOLEAN Recurse);
|
||||
|
||||
void Key_NtClose(HANDLE KeyHandle);
|
||||
void Key_NtClose(HANDLE KeyHandle, void* CloseParams);
|
||||
|
||||
HANDLE Key_GetTrueHandle(HANDLE KeyHandle, BOOLEAN *pIsOpenPath);
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ static NTSTATUS File_NtQueryVolumeInformationFile(
|
|||
|
||||
NTSTATUS File_NtCloseImpl(HANDLE FileHandle);
|
||||
|
||||
VOID File_NtCloseDir(HANDLE FileHandle);
|
||||
VOID File_NtCloseDir(HANDLE FileHandle, void* CloseParams);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Variables
|
||||
|
@ -484,7 +484,7 @@ _FX NTSTATUS File_Merge(
|
|||
|
||||
} else {
|
||||
|
||||
Handle_UnRegisterCloseHandler(merge->handle, File_NtCloseDir);
|
||||
Handle_UnRegisterHandler(merge->handle, File_NtCloseDir, NULL);
|
||||
List_Remove(&File_DirHandles, merge);
|
||||
File_MergeFree(merge);
|
||||
}
|
||||
|
@ -528,7 +528,7 @@ _FX NTSTATUS File_Merge(
|
|||
}
|
||||
|
||||
List_Insert_After(&File_DirHandles, NULL, merge);
|
||||
Handle_RegisterCloseHandler(merge->handle, File_NtCloseDir);
|
||||
Handle_RegisterHandler(merge->handle, File_NtCloseDir, NULL, FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2267,8 +2267,6 @@ _FX NTSTATUS File_NtCloseImpl(HANDLE FileHandle)
|
|||
THREAD_DATA *TlsData = Dll_GetTlsData(&LastError);
|
||||
|
||||
NTSTATUS status;
|
||||
ULONG i;
|
||||
P_CloseHandler CloseHandlers[MAX_CLOSE_HANDLERS];
|
||||
BOOLEAN DeleteOnClose = FALSE;
|
||||
UNICODE_STRING uni;
|
||||
WCHAR *DeletePath = NULL;
|
||||
|
@ -2308,13 +2306,7 @@ _FX NTSTATUS File_NtCloseImpl(HANDLE FileHandle)
|
|||
// and prepare the DeleteOnClose if its set
|
||||
//
|
||||
|
||||
if (Handle_FreeCloseHandler(FileHandle, &CloseHandlers[0], &DeleteOnClose)) {
|
||||
|
||||
for (i = 0; i < MAX_CLOSE_HANDLERS; i++) {
|
||||
if(CloseHandlers[i] != NULL)
|
||||
CloseHandlers[i](FileHandle);
|
||||
}
|
||||
}
|
||||
Handle_ExecuteCloseHandler(FileHandle, &DeleteOnClose);
|
||||
|
||||
//
|
||||
// prepare delete disposition if set
|
||||
|
@ -2397,7 +2389,7 @@ _FX NTSTATUS File_NtCloseImpl(HANDLE FileHandle)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX VOID File_NtCloseDir(HANDLE FileHandle)
|
||||
_FX VOID File_NtCloseDir(HANDLE FileHandle, void* CloseParams)
|
||||
{
|
||||
FILE_MERGE *merge;
|
||||
|
||||
|
@ -2407,7 +2399,6 @@ _FX VOID File_NtCloseDir(HANDLE FileHandle)
|
|||
while (merge) {
|
||||
FILE_MERGE *next = List_Next(merge);
|
||||
if (merge->handle == FileHandle) {
|
||||
Handle_UnRegisterCloseHandler(merge->handle, File_NtCloseDir);
|
||||
List_Remove(&File_DirHandles, merge);
|
||||
File_MergeFree(merge);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2020-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -348,7 +348,7 @@ _FX BOOLEAN File_RecordRecover(HANDLE FileHandle, const WCHAR *TruePath)
|
|||
//}
|
||||
|
||||
if (IsRecoverable != FALSE)
|
||||
Handle_RegisterCloseHandler(FileHandle, File_NotifyRecover);
|
||||
Handle_RegisterHandler(FileHandle, File_NotifyRecover, NULL, TRUE);
|
||||
|
||||
return IsRecoverable == TRUE;
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ _FX BOOLEAN File_RecordRecover(HANDLE FileHandle, const WCHAR *TruePath)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void File_NotifyRecover(HANDLE FileHandle)
|
||||
_FX void File_NotifyRecover(HANDLE FileHandle, void* CloseParams)
|
||||
{
|
||||
THREAD_DATA *TlsData = Dll_GetTlsData(NULL);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2021-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2021-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -33,10 +33,23 @@
|
|||
// Structures and Types
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
typedef struct _HANDLE_HANDLER
|
||||
{
|
||||
LIST_ELEM list_elem;
|
||||
|
||||
P_HandlerFunc Close;
|
||||
void* Param;
|
||||
|
||||
BOOL bPropagate; // incompatible with Param, todo: add duplicate handler
|
||||
|
||||
} HANDLE_HANDLER;
|
||||
|
||||
|
||||
typedef struct _HANDLE_STATE {
|
||||
|
||||
BOOLEAN DeleteOnClose;
|
||||
P_CloseHandler CloseHandlers[MAX_CLOSE_HANDLERS];
|
||||
LIST CloseHandlers;
|
||||
WCHAR* RelocationPath;
|
||||
|
||||
} HANDLE_STATE;
|
||||
|
@ -145,21 +158,17 @@ _FX WCHAR* Handle_GetRelocationPath(HANDLE FileHandle, ULONG ExtraLength)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX BOOLEAN Handle_FreeCloseHandler(HANDLE FileHandle, P_CloseHandler* CloseHandlers, BOOLEAN* DeleteOnClose)
|
||||
_FX VOID Handle_ExecuteCloseHandler(HANDLE FileHandle, BOOLEAN* DeleteOnClose)
|
||||
{
|
||||
BOOLEAN HasCloseHandlers = FALSE;
|
||||
LIST CloseHandlers;
|
||||
|
||||
EnterCriticalSection(&Handle_StatusData_CritSec);
|
||||
|
||||
HANDLE_STATE* state = (HANDLE_STATE*)map_get(&Handle_StatusData, FileHandle);
|
||||
if (state) {
|
||||
|
||||
HasCloseHandlers = TRUE;
|
||||
|
||||
if(CloseHandlers)
|
||||
memcpy(CloseHandlers, state->CloseHandlers, MAX_CLOSE_HANDLERS * sizeof(P_CloseHandler));
|
||||
if(DeleteOnClose) *DeleteOnClose = state->DeleteOnClose;
|
||||
|
||||
*DeleteOnClose = state->DeleteOnClose;
|
||||
CloseHandlers = state->CloseHandlers;
|
||||
if (state->RelocationPath) Dll_Free(state->RelocationPath);
|
||||
}
|
||||
|
||||
|
@ -167,22 +176,33 @@ _FX BOOLEAN Handle_FreeCloseHandler(HANDLE FileHandle, P_CloseHandler* CloseHand
|
|||
|
||||
LeaveCriticalSection(&Handle_StatusData_CritSec);
|
||||
|
||||
return HasCloseHandlers;
|
||||
//
|
||||
// execute all close handlers
|
||||
//
|
||||
|
||||
if (state) {
|
||||
while (1) {
|
||||
HANDLE_HANDLER* handler = List_Head(&CloseHandlers);
|
||||
if (!handler)
|
||||
break;
|
||||
handler->Close(FileHandle, handler->Param);
|
||||
List_Remove(&CloseHandlers, handler);
|
||||
Pool_Free(handler, sizeof(HANDLE_HANDLER));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Handle_RegisterCloseHandler
|
||||
// Handle_RegisterHandler
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX BOOLEAN Handle_RegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseHandler)
|
||||
_FX BOOLEAN Handle_RegisterHandler(HANDLE FileHandle, P_HandlerFunc CloseHandler, void* Params, BOOL bPropagate)
|
||||
{
|
||||
if (!FileHandle || FileHandle == (HANDLE)-1)
|
||||
return FALSE;
|
||||
|
||||
ULONG i;
|
||||
|
||||
EnterCriticalSection(&Handle_StatusData_CritSec);
|
||||
|
||||
HANDLE_STATE* state = map_get(&Handle_StatusData, FileHandle);
|
||||
|
@ -190,19 +210,30 @@ _FX BOOLEAN Handle_RegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseH
|
|||
state = map_insert(&Handle_StatusData, FileHandle, NULL, sizeof(HANDLE_STATE));
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_CLOSE_HANDLERS; i++) {
|
||||
if (state->CloseHandlers[i] == CloseHandler)
|
||||
HANDLE_HANDLER* handler = List_Head(&state->CloseHandlers);
|
||||
while (handler)
|
||||
{
|
||||
if (handler->Close == CloseHandler)
|
||||
break; // already registered
|
||||
if (state->CloseHandlers[i] == NULL) {
|
||||
state->CloseHandlers[i] = CloseHandler; // set to empty slot
|
||||
break;
|
||||
handler = List_Next(handler);
|
||||
}
|
||||
|
||||
if (handler == NULL)
|
||||
{
|
||||
HANDLE_HANDLER* newNandler = Pool_Alloc(Dll_Pool, sizeof(HANDLE_HANDLER));
|
||||
memzero(&newNandler->list_elem, sizeof(LIST_ELEM));
|
||||
|
||||
newNandler->Close = CloseHandler;
|
||||
newNandler->Param = Params;
|
||||
newNandler->bPropagate = bPropagate;
|
||||
|
||||
List_Insert_After(&state->CloseHandlers, NULL, newNandler);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&Handle_StatusData_CritSec);
|
||||
|
||||
if (i == MAX_CLOSE_HANDLERS) {
|
||||
SbieApi_Log(2301, L"No free CloseHandlers slot available");
|
||||
if (handler != NULL) {
|
||||
//SbieApi_Log(2301, L"CloseHandlers already registered"); // todo
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -211,30 +242,31 @@ _FX BOOLEAN Handle_RegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseH
|
|||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Handle_UnRegisterCloseHandler
|
||||
// Handle_UnRegisterHandler
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX BOOLEAN Handle_UnRegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseHandler)
|
||||
_FX VOID Handle_UnRegisterHandler(HANDLE FileHandle, P_HandlerFunc CloseHandler, void** pParams)
|
||||
{
|
||||
ULONG i = MAX_CLOSE_HANDLERS;
|
||||
|
||||
EnterCriticalSection(&Handle_StatusData_CritSec);
|
||||
|
||||
HANDLE_STATE* state = map_get(&Handle_StatusData, FileHandle);
|
||||
if (state) {
|
||||
|
||||
for (i = 0; i < MAX_CLOSE_HANDLERS; i++) {
|
||||
if (state->CloseHandlers[i] == CloseHandler) {
|
||||
state->CloseHandlers[i] = NULL; // clear slot
|
||||
HANDLE_HANDLER* handler = List_Head(&state->CloseHandlers);
|
||||
while (handler)
|
||||
{
|
||||
if (handler->Close == CloseHandler)
|
||||
{
|
||||
if (pParams) pParams = handler->Param;
|
||||
List_Remove(&state->CloseHandlers, handler);
|
||||
break;
|
||||
}
|
||||
handler = List_Next(handler);
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&Handle_StatusData_CritSec);
|
||||
|
||||
return i != MAX_CLOSE_HANDLERS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -245,8 +277,6 @@ _FX BOOLEAN Handle_UnRegisterCloseHandler(HANDLE FileHandle, P_CloseHandler Clos
|
|||
|
||||
_FX void Handle_SetupDuplicate(HANDLE OldFileHandle, HANDLE NewFileHandle)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
EnterCriticalSection(&Handle_StatusData_CritSec);
|
||||
|
||||
HANDLE_STATE* state = map_get(&Handle_StatusData, OldFileHandle);
|
||||
|
@ -255,16 +285,15 @@ _FX void Handle_SetupDuplicate(HANDLE OldFileHandle, HANDLE NewFileHandle)
|
|||
if(state->RelocationPath)
|
||||
Handle_SetRelocationPath(NewFileHandle, state->RelocationPath);
|
||||
|
||||
// todo: add a flag to each CloseHandlers entry to indicate if it should be propagated or not
|
||||
BOOLEAN found = FALSE;
|
||||
for (i = 0; i < MAX_CLOSE_HANDLERS; i++) {
|
||||
if (state->CloseHandlers[i] == File_NotifyRecover) {
|
||||
found = TRUE;
|
||||
HANDLE_HANDLER* handler = List_Head(&state->CloseHandlers);
|
||||
while (handler)
|
||||
{
|
||||
if (handler->bPropagate) {
|
||||
Handle_RegisterHandler(NewFileHandle, handler->Close, NULL, TRUE);
|
||||
break;
|
||||
}
|
||||
handler = List_Next(handler);
|
||||
}
|
||||
if(found)
|
||||
Handle_RegisterCloseHandler(NewFileHandle, File_NotifyRecover);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&Handle_StatusData_CritSec);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2021-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2021-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,10 +21,11 @@
|
|||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Defines
|
||||
// Structures and Types
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#define MAX_CLOSE_HANDLERS 4
|
||||
|
||||
typedef void(*P_HandlerFunc)(HANDLE handle, void* param);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -32,19 +33,17 @@
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
typedef void(*P_CloseHandler)(HANDLE handle);
|
||||
|
||||
VOID Handle_SetDeleteOnClose(HANDLE FileHandle, BOOLEAN DeleteOnClose);
|
||||
|
||||
BOOLEAN Handle_RegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseHandler);
|
||||
BOOLEAN Handle_RegisterHandler(HANDLE FileHandle, P_HandlerFunc CloseHandler, void* Params, BOOL bPropagate);
|
||||
|
||||
BOOLEAN Handle_UnRegisterCloseHandler(HANDLE FileHandle, P_CloseHandler CloseHandler);
|
||||
VOID Handle_UnRegisterHandler(HANDLE FileHandle, P_HandlerFunc CloseHandler, void** pParams);
|
||||
|
||||
VOID Handle_SetRelocationPath(HANDLE FileHandle, WCHAR* RelocationPath);
|
||||
|
||||
WCHAR* Handle_GetRelocationPath(HANDLE FileHandle, ULONG ExtraLength);
|
||||
|
||||
BOOLEAN Handle_FreeCloseHandler(HANDLE FileHandle, P_CloseHandler* CloseHandlers, BOOLEAN* DeleteOnClose);
|
||||
VOID Handle_ExecuteCloseHandler(HANDLE FileHandle, BOOLEAN* DeleteOnClose);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "dll.h"
|
||||
#include "obj.h"
|
||||
#include "handle.h"
|
||||
#include <stdio.h>
|
||||
#include "common/my_version.h"
|
||||
#include "core/svc/namedpipewire.h"
|
||||
|
@ -39,6 +40,32 @@
|
|||
: 0)
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Structures and Types
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
typedef struct _IPC_MERGE {
|
||||
|
||||
LIST_ELEM list_elem;
|
||||
|
||||
HANDLE handle;
|
||||
|
||||
LIST objects;
|
||||
|
||||
} IPC_MERGE;
|
||||
|
||||
|
||||
typedef struct _IPC_MERGE_ENTRY
|
||||
{
|
||||
LIST_ELEM list_elem;
|
||||
|
||||
UNICODE_STRING Name;
|
||||
UNICODE_STRING TypeName;
|
||||
|
||||
} IPC_MERGE_ENTRY;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Functions
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -356,6 +383,8 @@ LIST Ipc_DynamicPortNames;
|
|||
|
||||
BOOLEAN RpcRt_IsDynamicPortOpen(const WCHAR* wszPortName);
|
||||
|
||||
static LIST Ipc_Handles;
|
||||
static CRITICAL_SECTION Ipc_Handles_CritSec;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// IPC (other modules)
|
||||
|
@ -374,6 +403,10 @@ _FX BOOLEAN Ipc_Init(void)
|
|||
{
|
||||
HMODULE module = Dll_Ntdll;
|
||||
|
||||
InitializeCriticalSection(&Ipc_Handles_CritSec);
|
||||
|
||||
List_Init(&Ipc_Handles);
|
||||
|
||||
void *NtAlpcCreatePort;
|
||||
void *NtAlpcConnectPort;
|
||||
void *NtAlpcConnectPortEx;
|
||||
|
@ -744,7 +777,7 @@ _FX NTSTATUS Ipc_GetName(
|
|||
name = Dll_GetTlsNameBuffer(
|
||||
TlsData, TRUE_NAME_BUFFER, length + objname_len);
|
||||
|
||||
if ((! objname_len) || (! *objname_buf)) {
|
||||
/*if ((! objname_len) || (! *objname_buf)) {
|
||||
|
||||
//
|
||||
// an object handle was specified, but the object name is an
|
||||
|
@ -760,7 +793,7 @@ _FX NTSTATUS Ipc_GetName(
|
|||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (objname_len && *objname_buf == L'\\') {
|
||||
|
||||
|
@ -4071,6 +4104,152 @@ OpenTruePath:
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_MergeFree
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void Ipc_MergeFree(IPC_MERGE *merge)
|
||||
{
|
||||
while (1) {
|
||||
IPC_MERGE_ENTRY *entry = List_Head(&merge->objects);
|
||||
if (! entry)
|
||||
break;
|
||||
List_Remove(&merge->objects, entry);
|
||||
Dll_Free(entry);
|
||||
}
|
||||
|
||||
Dll_Free(merge);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_NtClose
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void Ipc_NtClose(HANDLE IpcHandle, void* CloseParams)
|
||||
{
|
||||
IPC_MERGE *merge;
|
||||
|
||||
EnterCriticalSection(&Ipc_Handles_CritSec);
|
||||
|
||||
merge = List_Head(&Ipc_Handles);
|
||||
while (merge) {
|
||||
if (merge->handle == IpcHandle) {
|
||||
|
||||
Handle_UnRegisterHandler(merge->handle, Ipc_NtClose, NULL);
|
||||
List_Remove(&Ipc_Handles, merge);
|
||||
Ipc_MergeFree(merge);
|
||||
|
||||
break;
|
||||
}
|
||||
merge = List_Next(merge);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&Ipc_Handles_CritSec);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_MergeDirectoryObject
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS Ipc_MergeDirectoryObject(IPC_MERGE *merge, WCHAR* path, BOOLEAN join)
|
||||
{
|
||||
NTSTATUS status;
|
||||
HANDLE directoryHandle;
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING objname;
|
||||
|
||||
RtlInitUnicodeString(&objname, path);
|
||||
|
||||
InitializeObjectAttributes(
|
||||
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
status = __sys_NtOpenDirectoryObject(&directoryHandle, DIRECTORY_QUERY, &objattrs);
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
ULONG bufferSize = 4096;
|
||||
PVOID buffer = Dll_Alloc(bufferSize);
|
||||
BOOLEAN firstTime = TRUE;
|
||||
ULONG indexCounter = 0;
|
||||
ULONG returnLength;
|
||||
|
||||
while (1)
|
||||
{
|
||||
status = __sys_NtQueryDirectoryObject(directoryHandle, buffer, bufferSize, FALSE, firstTime, &indexCounter, &returnLength);
|
||||
firstTime = FALSE;
|
||||
|
||||
if (status == STATUS_NO_MORE_ENTRIES)
|
||||
break; // done
|
||||
if (!NT_SUCCESS(status))
|
||||
break; // error
|
||||
|
||||
for (POBJECT_DIRECTORY_INFORMATION directoryInfo = buffer; directoryInfo->Name.Length != 0; directoryInfo++)
|
||||
{
|
||||
ULONG len = sizeof(IPC_MERGE_ENTRY) + (directoryInfo->Name.MaximumLength + directoryInfo->TypeName.MaximumLength) * sizeof(WCHAR);
|
||||
|
||||
//
|
||||
// when we are joining we remove the older entries when a duplicate is encountered
|
||||
//
|
||||
|
||||
if (join) {
|
||||
|
||||
IPC_MERGE_ENTRY* entry = List_Head(&merge->objects);
|
||||
while (entry) {
|
||||
|
||||
if (entry->Name.Length == directoryInfo->Name.Length && memcmp(entry->Name.Buffer, directoryInfo->Name.Buffer, entry->Name.Length) == 0)
|
||||
break;
|
||||
|
||||
entry = List_Next(entry);
|
||||
}
|
||||
|
||||
if (entry) {
|
||||
|
||||
if (entry->TypeName.Length == directoryInfo->TypeName.Length && memcmp(entry->TypeName.Buffer, directoryInfo->TypeName.Buffer, entry->TypeName.Length) == 0)
|
||||
continue; // identical entry, nothign to do
|
||||
|
||||
// same name but different type, remove old entry
|
||||
List_Remove(&merge->objects, entry);
|
||||
Dll_Free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// add new entry
|
||||
//
|
||||
|
||||
IPC_MERGE_ENTRY* entry = Dll_Alloc(len);
|
||||
WCHAR* ptr = entry + 1;
|
||||
|
||||
entry->Name.Length = directoryInfo->Name.Length;
|
||||
entry->Name.MaximumLength = directoryInfo->Name.MaximumLength;
|
||||
entry->Name.Buffer = ptr;
|
||||
memcpy(ptr, directoryInfo->Name.Buffer, directoryInfo->Name.MaximumLength);
|
||||
ptr += directoryInfo->Name.MaximumLength / sizeof(WCHAR);
|
||||
|
||||
entry->TypeName.Length = directoryInfo->TypeName.Length;
|
||||
entry->TypeName.MaximumLength = directoryInfo->TypeName.MaximumLength;
|
||||
entry->TypeName.Buffer = ptr;
|
||||
memcpy(ptr, directoryInfo->TypeName.Buffer, directoryInfo->TypeName.MaximumLength);
|
||||
//ptr += directoryInfo->TypeName.MaximumLength / sizeof(WCHAR);
|
||||
|
||||
List_Insert_After(&merge->objects, NULL, entry);
|
||||
}
|
||||
}
|
||||
|
||||
Dll_Free(buffer);
|
||||
|
||||
extern P_NtClose __sys_NtClose;
|
||||
__sys_NtClose(directoryHandle);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_NtQueryDirectoryObject
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -4085,8 +4264,133 @@ _FX NTSTATUS Ipc_NtQueryDirectoryObject(
|
|||
PULONG Context,
|
||||
PULONG ReturnLength)
|
||||
{
|
||||
SbieApi_Log(2205, L"NtQueryDirectoryObject");
|
||||
return __sys_NtQueryDirectoryObject(DirectoryHandle, Buffer, Length, ReturnSingleEntry, RestartScan, Context, ReturnLength);
|
||||
IPC_MERGE *merge;
|
||||
|
||||
EnterCriticalSection(&Ipc_Handles_CritSec);
|
||||
|
||||
merge = List_Head(&Ipc_Handles);
|
||||
while (merge) {
|
||||
|
||||
IPC_MERGE *next = List_Next(merge);
|
||||
|
||||
if (merge->handle == DirectoryHandle)
|
||||
break;
|
||||
|
||||
merge = next;
|
||||
}
|
||||
|
||||
if (RestartScan && merge != NULL) {
|
||||
|
||||
Handle_UnRegisterHandler(merge->handle, Ipc_NtClose, NULL);
|
||||
List_Remove(&Ipc_Handles, merge);
|
||||
Ipc_MergeFree(merge);
|
||||
|
||||
merge = NULL;
|
||||
}
|
||||
|
||||
if (! merge) {
|
||||
|
||||
merge = Dll_Alloc(sizeof(IPC_MERGE));
|
||||
memzero(merge, sizeof(IPC_MERGE));
|
||||
|
||||
merge->handle = DirectoryHandle;
|
||||
|
||||
List_Insert_Before(&Ipc_Handles, NULL, merge);
|
||||
Handle_RegisterHandler(merge->handle, Ipc_NtClose, NULL, FALSE);
|
||||
|
||||
WCHAR *TruePath;
|
||||
WCHAR *CopyPath;
|
||||
NTSTATUS status = Ipc_GetName(DirectoryHandle, NULL, &TruePath, &CopyPath, NULL);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
Ipc_MergeDirectoryObject(merge, TruePath, FALSE);
|
||||
|
||||
ULONG len = wcslen(CopyPath); // fix root copy path, remove tailing '\\'
|
||||
if (CopyPath[len - 1] == L'\\') CopyPath[len - 1] = 0;
|
||||
|
||||
Ipc_MergeDirectoryObject(merge, CopyPath, TRUE);
|
||||
}
|
||||
|
||||
//
|
||||
// goto index, for better performacne we could cache indexes
|
||||
//
|
||||
|
||||
IPC_MERGE_ENTRY* entry = List_Head(&merge->objects);
|
||||
|
||||
ULONG indexCounter = 0;
|
||||
if (Context) {
|
||||
for (; entry && indexCounter < *Context; indexCounter++)
|
||||
entry = List_Next(entry);
|
||||
}
|
||||
if (!entry)
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
|
||||
//
|
||||
// count the buffer space
|
||||
//
|
||||
|
||||
ULONG CountToGo = 0;
|
||||
ULONG TotalLength = sizeof(OBJECT_DIRECTORY_INFORMATION);
|
||||
for (IPC_MERGE_ENTRY* cur = entry; cur; cur = List_Next(cur)) {
|
||||
|
||||
ULONG len = sizeof(OBJECT_DIRECTORY_INFORMATION) + (cur->Name.MaximumLength + cur->TypeName.MaximumLength) * sizeof(WCHAR);
|
||||
|
||||
if (TotalLength + len > Length)
|
||||
break; // not enough space for this entry
|
||||
|
||||
CountToGo++;
|
||||
TotalLength += len;
|
||||
|
||||
if (ReturnSingleEntry)
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// fill output buffer
|
||||
//
|
||||
|
||||
POBJECT_DIRECTORY_INFORMATION directoryInfo = Buffer;
|
||||
WCHAR* ptr = directoryInfo + CountToGo + 1;
|
||||
|
||||
ULONG EndIndex = indexCounter + CountToGo;
|
||||
for (; entry && indexCounter < EndIndex; indexCounter++) {
|
||||
|
||||
directoryInfo->Name.Length = entry->Name.Length;
|
||||
directoryInfo->Name.MaximumLength = entry->Name.MaximumLength;
|
||||
directoryInfo->Name.Buffer = ptr;
|
||||
memcpy(ptr, entry->Name.Buffer, entry->Name.MaximumLength);
|
||||
ptr += directoryInfo->Name.MaximumLength / sizeof(WCHAR);
|
||||
|
||||
directoryInfo->TypeName.Length = entry->TypeName.Length;
|
||||
directoryInfo->TypeName.MaximumLength = entry->TypeName.MaximumLength;
|
||||
directoryInfo->TypeName.Buffer = ptr;
|
||||
memcpy(ptr, entry->TypeName.Buffer, entry->TypeName.MaximumLength);
|
||||
ptr += directoryInfo->TypeName.MaximumLength / sizeof(WCHAR);
|
||||
|
||||
directoryInfo++;
|
||||
|
||||
entry = List_Next(entry);
|
||||
}
|
||||
|
||||
//
|
||||
// terminate listing with an empty entry
|
||||
//
|
||||
|
||||
directoryInfo->Name.Length = directoryInfo->TypeName.Length = 0;
|
||||
directoryInfo->Name.MaximumLength = directoryInfo->TypeName.MaximumLength = 0;
|
||||
directoryInfo->Name.Buffer = directoryInfo->TypeName.Buffer = NULL;
|
||||
|
||||
//
|
||||
// set return values
|
||||
//
|
||||
|
||||
if (ReturnLength) *ReturnLength = TotalLength;
|
||||
if (Context) *Context = indexCounter;
|
||||
if (indexCounter < (ULONG)merge->objects.count)
|
||||
return STATUS_MORE_ENTRIES;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2021-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2021-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -206,7 +206,7 @@ _FX NTSTATUS Key_Merge(
|
|||
// if we got here, we need to discard the stale entry
|
||||
//
|
||||
|
||||
Handle_UnRegisterCloseHandler(merge->handle, Key_NtClose);
|
||||
Handle_UnRegisterHandler(merge->handle, Key_NtClose, NULL);
|
||||
List_Remove(&Key_Handles, merge);
|
||||
Key_MergeFree(merge, TRUE);
|
||||
|
||||
|
@ -234,7 +234,7 @@ _FX NTSTATUS Key_Merge(
|
|||
memcpy(merge->name, TruePath, TruePath_len + sizeof(WCHAR));
|
||||
|
||||
List_Insert_Before(&Key_Handles, NULL, merge);
|
||||
Handle_RegisterCloseHandler(merge->handle, Key_NtClose);
|
||||
Handle_RegisterHandler(merge->handle, Key_NtClose, NULL, FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1557,7 +1557,7 @@ _FX void Key_DiscardMergeByPath(const WCHAR *TruePath, BOOLEAN Recurse)
|
|||
}
|
||||
}
|
||||
|
||||
Handle_UnRegisterCloseHandler(merge->handle, Key_NtClose);
|
||||
Handle_UnRegisterHandler(merge->handle, Key_NtClose, NULL);
|
||||
List_Remove(&Key_Handles, merge);
|
||||
Key_MergeFree(merge, TRUE);
|
||||
}
|
||||
|
@ -1605,7 +1605,7 @@ _FX void Key_DiscardMergeByHandle(
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void Key_NtClose(HANDLE KeyHandle)
|
||||
_FX void Key_NtClose(HANDLE KeyHandle, void* CloseParams)
|
||||
{
|
||||
KEY_MERGE *merge;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020-2021 David Xanatos, xanasoft.com
|
||||
* Copyright 2020-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -219,7 +219,7 @@ _FX HANDLE Scm_CreateWaitableTimerW(
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX VOID Scm_TokenCloseHandler(HANDLE Handle)
|
||||
_FX VOID Scm_TokenCloseHandler(HANDLE Handle, void* CloseParams)
|
||||
{
|
||||
THREAD_DATA *TlsData = Dll_GetTlsData(NULL);
|
||||
|
||||
|
@ -241,7 +241,7 @@ _FX BOOL Scm_OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE
|
|||
|
||||
if (NT_SUCCESS(status) && ProcessHandle == GetCurrentProcess()) {
|
||||
|
||||
Handle_RegisterCloseHandler(*phTokenOut, Scm_TokenCloseHandler);
|
||||
Handle_RegisterHandler(*phTokenOut, Scm_TokenCloseHandler, NULL, FALSE);
|
||||
TlsData->scm_last_own_token = *phTokenOut;
|
||||
}
|
||||
|
||||
|
@ -262,7 +262,7 @@ _FX BOOL Scm_OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL Open
|
|||
|
||||
if (NT_SUCCESS(status) && ThreadHandle == GetCurrentThread()) {
|
||||
|
||||
Handle_RegisterCloseHandler(*phTokenOut, Scm_TokenCloseHandler);
|
||||
Handle_RegisterHandler(*phTokenOut, Scm_TokenCloseHandler, NULL, FALSE);
|
||||
TlsData->scm_last_own_token = *phTokenOut;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -738,7 +739,7 @@ _FX NTSTATUS Secure_NtDuplicateObject(
|
|||
}
|
||||
|
||||
if (SourceHandle)
|
||||
Key_NtClose(SourceHandle);
|
||||
Key_NtClose(SourceHandle, NULL);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue