In kernel mode, GS base is not set to a TEB, but fortunately the offset for the current thread object, which EasyAntiCheat.sys relies on, doesn't conflict with anything in the TEB.
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- v2: Add comment explaining position. --- dlls/ntoskrnl.exe/ntoskrnl.c | 37 +++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index d407cffee69..7fb01464816 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -870,7 +870,7 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
for (;;) { - NtCurrentTeb()->Reserved5[1] = NULL; + NtCurrentTeb()->SystemReserved1[15] = NULL; if (!context.in_buff && !(context.in_buff = HeapAlloc( GetProcessHeap(), 0, context.in_size ))) { ERR( "failed to allocate buffer\n" ); @@ -891,7 +891,7 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) context.params = reply->params; context.in_size = reply->in_size; client_tid = reply->client_tid; - NtCurrentTeb()->Reserved5[1] = wine_server_get_ptr( reply->client_thread ); + NtCurrentTeb()->SystemReserved1[15] = wine_server_get_ptr( reply->client_thread ); } else { @@ -2339,7 +2339,7 @@ POBJECT_TYPE PsThreadType = &thread_type; */ PRKTHREAD WINAPI KeGetCurrentThread(void) { - struct _KTHREAD *thread = NtCurrentTeb()->Reserved5[1]; + struct _KTHREAD *thread = NtCurrentTeb()->SystemReserved1[15];
if (!thread) { @@ -2352,7 +2352,11 @@ PRKTHREAD WINAPI KeGetCurrentThread(void) kernel_object_from_handle( handle, PsThreadType, (void**)&thread ); if (handle != GetCurrentThread()) NtClose( handle );
- NtCurrentTeb()->Reserved5[1] = thread; + /* In kernel mode, GS base is not set to a TEB, but fortunately the offset + for the current thread object, which EasyAntiCheat.sys relies on, + doesn't conflict with anything in the TEB. */ + + NtCurrentTeb()->SystemReserved1[15] = thread; }
return thread; @@ -2881,6 +2885,22 @@ DEVICE_OBJECT* WINAPI IoGetAttachedDeviceReference( DEVICE_OBJECT *device ) }
+struct system_thread_ctx +{ + PKSTART_ROUTINE start; + PVOID context; +}; + +static void WINAPI init_system_thread(PVOID context) +{ + struct system_thread_ctx info = *(struct system_thread_ctx *)context; + HeapFree( GetProcessHeap(), 0, context ); + + NtCurrentTeb()->SystemReserved1[15] = KeGetCurrentThread(); + + info.start(info.context); +} + /*********************************************************************** * PsCreateSystemThread (NTOSKRNL.EXE.@) */ @@ -2889,9 +2909,16 @@ NTSTATUS WINAPI PsCreateSystemThread(PHANDLE ThreadHandle, ULONG DesiredAccess, HANDLE ProcessHandle, PCLIENT_ID ClientId, PKSTART_ROUTINE StartRoutine, PVOID StartContext) { + struct system_thread_ctx *info; + if (!ProcessHandle) ProcessHandle = GetCurrentProcess(); + + info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) ); + info->start = StartRoutine; + info->context = StartContext; + return RtlCreateUserThread(ProcessHandle, 0, FALSE, 0, 0, - 0, StartRoutine, StartContext, + 0, init_system_thread, info, ThreadHandle, ClientId); }
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 32 +++++++++++++++++++++++++++++ dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 7fb01464816..5f0d035c65d 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -2811,6 +2811,38 @@ NTSTATUS WINAPI ObReferenceObjectByName( UNICODE_STRING *ObjectName, }
+/******************************************************************** + * ObOpenObjectByName (NTOSKRNL.EXE.@) + */ +NTSTATUS WINAPI ObOpenObjectByName(POBJECT_ATTRIBUTES attr, POBJECT_TYPE type, + KPROCESSOR_MODE mode, ACCESS_STATE *access_state, + ACCESS_MASK access, PVOID ctx, HANDLE *handle) +{ + NTSTATUS status; + void *object; + + TRACE( "attr(%p %s %x) %p %u %p %u %p %p\n", attr->RootDirectory, debugstr_us(attr->ObjectName), + attr->Attributes, type, mode, access_state, access, ctx, handle ); + + if (mode != KernelMode) + { + FIXME( "UserMode access not implemented\n" ); + return STATUS_NOT_IMPLEMENTED; + } + + if (attr->RootDirectory) FIXME( "RootDirectory unhandled\n" ); + + status = ObReferenceObjectByName(attr->ObjectName, attr->Attributes, access_state, access, type, mode, ctx, &object ); + if (status != STATUS_SUCCESS) + return status; + + status = ObOpenObjectByPointer(object, attr->Attributes, access_state, access, type, mode, handle); + + ObDereferenceObject(object); + return status; +} + + /*********************************************************************** * ObReferenceObjectByPointer (NTOSKRNL.EXE.@) */ diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 6acdec5dc5a..34fde20f8a4 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -835,7 +835,7 @@ @ stub ObInsertObject @ stub ObLogSecurityDescriptor @ stub ObMakeTemporaryObject -@ stub ObOpenObjectByName +@ stdcall ObOpenObjectByName(ptr ptr long ptr long ptr ptr) @ stdcall ObOpenObjectByPointer(ptr long ptr long ptr long ptr) @ stdcall ObQueryNameString(ptr ptr long ptr) @ stub ObQueryObjectAuditingByHandle
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- v2: - Added tests. - Added header definition. --- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- dlls/ntoskrnl.exe/sync.c | 22 ++++++++++++++++++++++ dlls/ntoskrnl.exe/tests/driver.c | 11 +++++++++++ include/ddk/wdm.h | 1 + 4 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 34fde20f8a4..b2d7d8b9640 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -599,7 +599,7 @@ @ stdcall KeQueryTickCount(ptr) @ stdcall KeQueryTimeIncrement() @ stub KeRaiseUserException -@ stub KeReadStateEvent +@ stdcall KeReadStateEvent(ptr) @ stub KeReadStateMutant @ stub KeReadStateMutex @ stub KeReadStateQueue diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c index 5e06ab2f2b6..7f19ce7571b 100644 --- a/dlls/ntoskrnl.exe/sync.c +++ b/dlls/ntoskrnl.exe/sync.c @@ -311,6 +311,28 @@ void WINAPI KeClearEvent( PRKEVENT event ) KeResetEvent( event ); }
+/*********************************************************************** + * KeReadStateEvent (NTOSKRNL.EXE.@) + */ +LONG WINAPI KeReadStateEvent( PRKEVENT event ) +{ + HANDLE handle; + + TRACE("event %p.\n", event); + + if (event->Header.WaitListHead.Blink == INVALID_HANDLE_VALUE) + { + if (!(ObOpenObjectByPointer( event, OBJ_KERNEL_HANDLE, NULL, EVENT_QUERY_STATE, NULL, KernelMode, &handle ))) + { + EVENT_BASIC_INFORMATION event_info; + if (!(NtQueryEvent( handle, EventBasicInformation, &event_info, sizeof(event_info), NULL))) + event->Header.SignalState = event_info.EventState; + NtClose( handle ); + } + } + return event->Header.SignalState; +} + /*********************************************************************** * KeInitializeSemaphore (NTOSKRNL.EXE.@) */ diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index bb5bbeb4fa5..d1503f824ef 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -447,8 +447,14 @@ static void test_sync(void) ret = wait_single(&manual_event, 0); ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
+ ret = KeReadStateEvent(&manual_event); + ok(ret == 0, "got %d\n", ret); + KeSetEvent(&manual_event, 0, FALSE);
+ ret = KeReadStateEvent(&manual_event); + ok(ret == 1, "got %d\n", ret); + ret = wait_single(&manual_event, 0); ok(ret == 0, "got %#x\n", ret);
@@ -541,9 +547,14 @@ static void test_sync(void) ret = ObReferenceObjectByHandle(handle, SYNCHRONIZE, *pExEventObjectType, KernelMode, (void **)&event, NULL); ok(!ret, "ObReferenceObjectByHandle failed: %#x\n", ret);
+ ret = wait_single(event, 0); ok(ret == 0, "got %#x\n", ret); + ret = KeReadStateEvent(event); + ok(ret == 1, "got %d\n", ret); KeResetEvent(event); + ret = KeReadStateEvent(event); + ok(ret == 0, "got %d\n", ret); ret = wait_single(event, 0); ok(ret == STATUS_TIMEOUT, "got %#x\n", ret); ret = wait_single_handle(handle, 0); diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 59af860708b..176b432644a 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1759,6 +1759,7 @@ KAFFINITY WINAPI KeQueryActiveProcessors(void); void WINAPI KeQuerySystemTime(LARGE_INTEGER*); void WINAPI KeQueryTickCount(LARGE_INTEGER*); ULONG WINAPI KeQueryTimeIncrement(void); +LONG WINAPI KeReadStateEvent(PRKEVENT); void FASTCALL KeReleaseInStackQueuedSpinLockFromDpcLevel(KLOCK_QUEUE_HANDLE*); LONG WINAPI KeReleaseMutex(PRKMUTEX,BOOLEAN); LONG WINAPI KeReleaseSemaphore(PRKSEMAPHORE,KPRIORITY,LONG,BOOLEAN);
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- dlls/ntoskrnl.exe/sync.c | 33 +++++++++++++++++++++++++++++ include/ddk/wdm.h | 7 ++++++ 3 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index b2d7d8b9640..37ac3effad3 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -564,7 +564,7 @@ @ stub KeI386ReleaseLid @ stub KeI386SetGdtSelector @ stub KeIcacheFlushCount -@ stub KeInitializeApc +@ stdcall KeInitializeApc(ptr ptr long ptr ptr ptr long ptr) @ stub KeInitializeDeviceQueue @ stdcall KeInitializeDpc(ptr ptr ptr) @ stdcall KeInitializeEvent(ptr long long) diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c index 7f19ce7571b..c67c4f01573 100644 --- a/dlls/ntoskrnl.exe/sync.c +++ b/dlls/ntoskrnl.exe/sync.c @@ -33,6 +33,7 @@ #include "wine/asm.h" #include "wine/debug.h" #include "wine/heap.h" +#include "wine/server.h"
#include "ntoskrnl_private.h"
@@ -663,6 +664,38 @@ void WINAPI KeReleaseInStackQueuedSpinLock( KLOCK_QUEUE_HANDLE *queue ) } #endif
+/*********************************************************************** + * KeInitializeApc (NTOSKRNL.EXE.@) + */ +void WINAPI KeInitializeApc(PRKAPC apc, PRKTHREAD thread, KAPC_ENVIRONMENT env, PKKERNEL_ROUTINE krnl_routine, + PKRUNDOWN_ROUTINE rundown_routine, PKNORMAL_ROUTINE normal_routine, KPROCESSOR_MODE apc_mode, PVOID ctx) +{ + TRACE("apc %p thread %p env %u krnl_routine %p rundown_routine %p normal_routine %p apc_mode %u ctx %p\n", + apc, thread, env, krnl_routine, rundown_routine, normal_routine, apc_mode, ctx); + + if (env != OriginalApcEnvironment) + FIXME("Unhandled APC_ENVIRONMENT\n"); + + apc->Type = 18; + apc->Size = sizeof(*apc); + apc->Thread = thread; + apc->ApcStateIndex = env; + apc->KernelRoutine = krnl_routine; + apc->RundownRoutine = rundown_routine; + apc->NormalRoutine = normal_routine; + apc->Inserted = FALSE; + if (apc->NormalRoutine) + { + apc->ApcMode = apc_mode; + apc->NormalContext = ctx; + } + else + { + apc->ApcMode = KernelMode; + apc->NormalContext = NULL; + } +} + static KSPIN_LOCK cancel_lock;
/*********************************************************************** diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 176b432644a..9fcb1387012 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -464,6 +464,13 @@ typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; /* Irp definitions */ typedef UCHAR KIRQL, *PKIRQL; typedef CCHAR KPROCESSOR_MODE; +typedef enum _KAPC_ENVIRONMENT +{ + OriginalApcEnvironment, + AttachedApcEnvironment, + CurrentApcEnvironment, + InsertApcEnvironment +} KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT;
typedef VOID (WINAPI *PDRIVER_CANCEL)( IN struct _DEVICE_OBJECT *DeviceObject,
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- v2: Fixed function definition. --- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 ++ dlls/ntoskrnl.exe/sync.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 37ac3effad3..d3f9bbdd862 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -529,6 +529,7 @@ @ stdcall KeAcquireSpinLockAtDpcLevel(ptr) @ stdcall -arch=!i386 KeAcquireSpinLockRaiseToDpc(ptr) @ stub KeAddSystemServiceTable +@ stdcall KeAlertThread(ptr long) @ stdcall KeAreApcsDisabled() @ stub KeAttachProcess @ stdcall KeBugCheck(long) @@ -647,6 +648,7 @@ @ stdcall KeStackAttachProcess(ptr ptr) @ stub KeSynchronizeExecution @ stub KeTerminateThread +@ stdcall KeTestAlertThread(long) @ extern KeTickCount @ stdcall KeUnstackDetachProcess(ptr) @ stub KeUpdateRunTime diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c index c67c4f01573..0ddb1b353c5 100644 --- a/dlls/ntoskrnl.exe/sync.c +++ b/dlls/ntoskrnl.exe/sync.c @@ -696,6 +696,24 @@ void WINAPI KeInitializeApc(PRKAPC apc, PRKTHREAD thread, KAPC_ENVIRONMENT env, } }
+/*********************************************************************** + * KeTestAlertThread (NTOSKRNL.EXE.@) + */ +BOOLEAN WINAPI KeTestAlertThread(KPROCESSOR_MODE mode) +{ + FIXME("stub! %u\n", mode); + return TRUE; +} + +/*********************************************************************** + * KeAlertThread (NTOSKRNL.EXE.@) + */ +BOOLEAN WINAPI KeAlertThread(PKTHREAD thread, KPROCESSOR_MODE mode) +{ + FIXME("stub! %p mode %u\n", thread, mode); + return TRUE; +} + static KSPIN_LOCK cancel_lock;
/***********************************************************************