mirror of
https://github.com/decompals/wibo.git
synced 2025-12-12 22:56:13 +00:00
New handles, threading and processes subsystems
This commit is contained in:
@@ -1,11 +1,8 @@
|
||||
#include "handleapi.h"
|
||||
|
||||
#include "dll/advapi32/internal.h"
|
||||
#include "errors.h"
|
||||
#include "files.h"
|
||||
#include "handles.h"
|
||||
#include "internal.h"
|
||||
#include "processes.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
@@ -17,7 +14,6 @@ BOOL WIN_FUNC DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle,
|
||||
DEBUG_LOG("DuplicateHandle(%p, %p, %p, %p, %x, %d, %x)\n", hSourceProcessHandle, hSourceHandle,
|
||||
hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
|
||||
(void)dwDesiredAccess;
|
||||
(void)bInheritHandle;
|
||||
(void)dwOptions;
|
||||
if (!lpTargetHandle) {
|
||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||
@@ -25,15 +21,10 @@ BOOL WIN_FUNC DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle,
|
||||
}
|
||||
|
||||
auto validateProcessHandle = [&](HANDLE handle) -> bool {
|
||||
uintptr_t raw = reinterpret_cast<uintptr_t>(handle);
|
||||
if (raw == static_cast<uintptr_t>(-1)) {
|
||||
if (reinterpret_cast<uintptr_t>(handle) == kPseudoCurrentProcessHandleValue) {
|
||||
return true;
|
||||
}
|
||||
auto data = handles::dataFromHandle(handle, false);
|
||||
if (data.type != handles::TYPE_PROCESS || data.ptr == nullptr) {
|
||||
return false;
|
||||
}
|
||||
auto *proc = reinterpret_cast<processes::Process *>(data.ptr);
|
||||
auto proc = wibo::handles().getAs<ProcessObject>(handle);
|
||||
return proc && proc->pid == getpid();
|
||||
};
|
||||
|
||||
@@ -44,125 +35,35 @@ BOOL WIN_FUNC DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto file = files::fileHandleFromHandle(hSourceHandle);
|
||||
if (file && (file->fp == stdin || file->fp == stdout || file->fp == stderr)) {
|
||||
HANDLE handle = files::duplicateFileHandle(file, false);
|
||||
DEBUG_LOG("DuplicateHandle: duplicated std handle -> %p\n", handle);
|
||||
*lpTargetHandle = handle;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
uintptr_t sourceHandleRaw = reinterpret_cast<uintptr_t>(hSourceHandle);
|
||||
if (sourceHandleRaw == static_cast<uintptr_t>(-1)) {
|
||||
HANDLE handle = processes::allocProcessHandle(getpid());
|
||||
processes::Process *proc = processes::processFromHandle(handle, false);
|
||||
if (proc) {
|
||||
proc->exitCode = STILL_ACTIVE;
|
||||
proc->forcedExitCode = STILL_ACTIVE;
|
||||
proc->terminationRequested = false;
|
||||
}
|
||||
if (sourceHandleRaw == kPseudoCurrentProcessHandleValue) {
|
||||
auto po = make_pin<ProcessObject>(getpid(), -1);
|
||||
auto handle = wibo::handles().alloc(std::move(po), 0, 0);
|
||||
DEBUG_LOG("DuplicateHandle: created process handle for current process -> %p\n", handle);
|
||||
*lpTargetHandle = handle;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
if (sourceHandleRaw == kPseudoCurrentThreadHandleValue) {
|
||||
ThreadObject *obj = ensureCurrentThreadObject();
|
||||
if (obj) {
|
||||
retainThreadObject(obj);
|
||||
HANDLE handle = handles::allocDataHandle({handles::TYPE_THREAD, obj, 0});
|
||||
DEBUG_LOG("DuplicateHandle: duplicated pseudo current thread -> %p\n", handle);
|
||||
*lpTargetHandle = handle;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
ThreadObject *syntheticObj = new ThreadObject();
|
||||
syntheticObj->thread = pthread_self();
|
||||
syntheticObj->finished = false;
|
||||
syntheticObj->joined = false;
|
||||
syntheticObj->detached = true;
|
||||
syntheticObj->synthetic = true;
|
||||
syntheticObj->exitCode = 0;
|
||||
syntheticObj->refCount = 1;
|
||||
syntheticObj->suspendCount = 0;
|
||||
pthread_mutex_init(&syntheticObj->mutex, nullptr);
|
||||
pthread_cond_init(&syntheticObj->cond, nullptr);
|
||||
HANDLE handle = handles::allocDataHandle({handles::TYPE_THREAD, syntheticObj, 0});
|
||||
DEBUG_LOG("DuplicateHandle: created synthetic thread handle -> %p\n", handle);
|
||||
} else if (sourceHandleRaw == kPseudoCurrentThreadHandleValue) {
|
||||
auto th = make_pin<ThreadObject>(pthread_self());
|
||||
auto handle = wibo::handles().alloc(std::move(th), 0, 0);
|
||||
DEBUG_LOG("DuplicateHandle: created thread handle for current thread -> %p\n", handle);
|
||||
*lpTargetHandle = handle;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
handles::Data data = handles::dataFromHandle(hSourceHandle, false);
|
||||
if (data.type == handles::TYPE_PROCESS && data.ptr) {
|
||||
auto *original = reinterpret_cast<processes::Process *>(data.ptr);
|
||||
HANDLE handle = processes::allocProcessHandle(original->pid);
|
||||
auto *copy = processes::processFromHandle(handle, false);
|
||||
if (copy) {
|
||||
*copy = *original;
|
||||
}
|
||||
DEBUG_LOG("DuplicateHandle: duplicated process handle -> %p\n", handle);
|
||||
*lpTargetHandle = handle;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
if (!wibo::handles().duplicateTo(hSourceHandle, wibo::handles(), *lpTargetHandle, dwDesiredAccess, bInheritHandle,
|
||||
dwOptions)) {
|
||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
if (data.type == handles::TYPE_THREAD && data.ptr) {
|
||||
auto *threadObj = reinterpret_cast<ThreadObject *>(data.ptr);
|
||||
if (!retainThreadObject(threadObj)) {
|
||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
HANDLE handle = handles::allocDataHandle({handles::TYPE_THREAD, threadObj, 0});
|
||||
DEBUG_LOG("DuplicateHandle: duplicated thread handle -> %p\n", handle);
|
||||
*lpTargetHandle = handle;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
DEBUG_LOG("DuplicateHandle: unsupported handle type for %p\n", hSourceHandle);
|
||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||
return FALSE;
|
||||
wibo::lastError = ERROR_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WIN_FUNC CloseHandle(HANDLE hObject) {
|
||||
DEBUG_LOG("CloseHandle(%p)\n", hObject);
|
||||
auto data = handles::dataFromHandle(hObject, true);
|
||||
if (data.type == handles::TYPE_UNUSED || data.ptr == nullptr) {
|
||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
bool success = true;
|
||||
if (data.type == handles::TYPE_FILE) {
|
||||
auto file = reinterpret_cast<files::FileHandle *>(data.ptr);
|
||||
if (file) {
|
||||
if (file->closeOnDestroy && file->fp && !(file->fp == stdin || file->fp == stdout || file->fp == stderr)) {
|
||||
fclose(file->fp);
|
||||
}
|
||||
delete file;
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
} else if (data.type == handles::TYPE_MAPPED) {
|
||||
if (!closeFileMappingHandle(data.ptr)) {
|
||||
success = false;
|
||||
}
|
||||
} else if (data.type == handles::TYPE_PROCESS) {
|
||||
delete reinterpret_cast<processes::Process *>(data.ptr);
|
||||
} else if (data.type == handles::TYPE_TOKEN) {
|
||||
delete reinterpret_cast<TokenObject *>(data.ptr);
|
||||
} else if (data.type == handles::TYPE_MUTEX) {
|
||||
releaseMutexObject(reinterpret_cast<MutexObject *>(data.ptr));
|
||||
} else if (data.type == handles::TYPE_EVENT) {
|
||||
releaseEventObject(reinterpret_cast<EventObject *>(data.ptr));
|
||||
} else if (data.type == handles::TYPE_THREAD) {
|
||||
releaseThreadObject(reinterpret_cast<ThreadObject *>(data.ptr));
|
||||
} else if (data.type == handles::TYPE_SEMAPHORE) {
|
||||
releaseSemaphoreObject(reinterpret_cast<SemaphoreObject *>(data.ptr));
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
if (!success) {
|
||||
if (!wibo::handles().release(hObject)) {
|
||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user