192 lines
5.0 KiB
C
192 lines
5.0 KiB
C
/*
|
|
* Win32 'syslevel' routines
|
|
*
|
|
* Copyright 1998 Ulrich Weigand
|
|
*/
|
|
|
|
#include <unistd.h>
|
|
#include "syslevel.h"
|
|
#include "heap.h"
|
|
#include "stackframe.h"
|
|
#include "debug.h"
|
|
|
|
DEFAULT_DEBUG_CHANNEL(win32)
|
|
|
|
static CRITICAL_SECTION Win16Mutex;
|
|
static SEGPTR segpWin16Mutex;
|
|
|
|
/* Global variable to save current TEB while in 16-bit code */
|
|
WORD SYSLEVEL_Win16CurrentTeb = 0;
|
|
|
|
/* TEB of initial process for emergency use */
|
|
WORD SYSLEVEL_EmergencyTeb = 0;
|
|
|
|
|
|
/************************************************************************
|
|
* SYSLEVEL_Init
|
|
*/
|
|
void SYSLEVEL_Init(void)
|
|
{
|
|
CRITICAL_SECTION **w16Mutex = SEGPTR_ALLOC(sizeof(CRITICAL_SECTION *));
|
|
|
|
*w16Mutex = &Win16Mutex;
|
|
segpWin16Mutex = SEGPTR_GET(w16Mutex);
|
|
|
|
InitializeCriticalSection(&Win16Mutex);
|
|
MakeCriticalSectionGlobal(&Win16Mutex);
|
|
}
|
|
|
|
/************************************************************************
|
|
* GetpWin16Lock32 (KERNEL32.93)
|
|
*/
|
|
VOID WINAPI GetpWin16Lock(CRITICAL_SECTION **lock)
|
|
{
|
|
*lock = &Win16Mutex;
|
|
}
|
|
|
|
/************************************************************************
|
|
* GetpWin16Lock16 (KERNEL.449)
|
|
*/
|
|
SEGPTR WINAPI GetpWin16Lock16(void)
|
|
{
|
|
return segpWin16Mutex;
|
|
}
|
|
|
|
/************************************************************************
|
|
* _EnterSysLevel (KERNEL32.97)
|
|
*/
|
|
VOID WINAPI _EnterSysLevel(CRITICAL_SECTION *lock)
|
|
{
|
|
EnterCriticalSection(lock);
|
|
|
|
if (lock == &Win16Mutex)
|
|
GET_FS( SYSLEVEL_Win16CurrentTeb );
|
|
}
|
|
|
|
/************************************************************************
|
|
* _LeaveSysLevel (KERNEL32.98)
|
|
*/
|
|
VOID WINAPI _LeaveSysLevel(CRITICAL_SECTION *lock)
|
|
{
|
|
LeaveCriticalSection(lock);
|
|
}
|
|
|
|
/************************************************************************
|
|
* (KERNEL32.86)
|
|
*/
|
|
VOID WINAPI _KERNEL32_86(CRITICAL_SECTION *lock)
|
|
{
|
|
_LeaveSysLevel(lock);
|
|
}
|
|
|
|
/************************************************************************
|
|
* SYSLEVEL_EnterWin16Lock [KERNEL.480]
|
|
*/
|
|
VOID WINAPI SYSLEVEL_EnterWin16Lock(VOID)
|
|
{
|
|
TRACE(win32, "thread %04x (pid %d) about to enter\n",
|
|
THREAD_Current()->teb_sel, getpid());
|
|
|
|
_EnterSysLevel(&Win16Mutex);
|
|
|
|
TRACE(win32, "thread %04x (pid %d) entered, count is %ld\n",
|
|
THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
|
|
}
|
|
|
|
/************************************************************************
|
|
* SYSLEVEL_LeaveWin16Lock [KERNEL.481]
|
|
*/
|
|
VOID WINAPI SYSLEVEL_LeaveWin16Lock(VOID)
|
|
{
|
|
TRACE(win32, "thread %04x (pid %d) about to leave, count is %ld\n",
|
|
THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
|
|
|
|
_LeaveSysLevel(&Win16Mutex);
|
|
}
|
|
|
|
/************************************************************************
|
|
* _CheckNotSysLevel (KERNEL32.94)
|
|
*/
|
|
VOID WINAPI _CheckNotSysLevel(CRITICAL_SECTION *lock)
|
|
{
|
|
FIXME(win32, "()\n");
|
|
}
|
|
|
|
/************************************************************************
|
|
* _ConfirmSysLevel (KERNEL32.95)
|
|
*/
|
|
VOID WINAPI _ConfirmSysLevel(CRITICAL_SECTION *lock)
|
|
{
|
|
FIXME(win32, "()\n");
|
|
}
|
|
|
|
/************************************************************************
|
|
* _ConfirmWin16Lock (KERNEL32.96)
|
|
*/
|
|
DWORD WINAPI _ConfirmWin16Lock(void)
|
|
{
|
|
if ( Win16Mutex.OwningThread == GetCurrentThreadId() )
|
|
return Win16Mutex.RecursionCount;
|
|
else
|
|
return 0L;
|
|
}
|
|
|
|
/************************************************************************
|
|
* ReleaseThunkLock (KERNEL32.48)
|
|
*/
|
|
VOID WINAPI ReleaseThunkLock(DWORD *mutex_count)
|
|
{
|
|
DWORD count = Win16Mutex.RecursionCount;
|
|
*mutex_count = count;
|
|
|
|
while (count-- > 0)
|
|
_LeaveSysLevel(&Win16Mutex);
|
|
}
|
|
|
|
/************************************************************************
|
|
* RestoreThunkLock (KERNEL32.49)
|
|
*/
|
|
VOID WINAPI RestoreThunkLock(DWORD mutex_count)
|
|
{
|
|
while (mutex_count-- > 0)
|
|
_EnterSysLevel(&Win16Mutex);
|
|
}
|
|
|
|
/************************************************************************
|
|
* SYSLEVEL_ReleaseWin16Lock
|
|
*/
|
|
VOID SYSLEVEL_ReleaseWin16Lock(VOID)
|
|
{
|
|
DWORD count;
|
|
|
|
TRACE(win32, "thread %04x (pid %d) about to release, count is %ld\n",
|
|
THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
|
|
|
|
ReleaseThunkLock(&count);
|
|
|
|
if (count > 0xffff)
|
|
ERR(win32, "Win16Mutex recursion count too large!\n");
|
|
|
|
CURRENT_STACK16->mutex_count = (WORD)count;
|
|
}
|
|
|
|
/************************************************************************
|
|
* SYSLEVEL_RestoreWin16Lock
|
|
*/
|
|
VOID SYSLEVEL_RestoreWin16Lock(VOID)
|
|
{
|
|
DWORD count = CURRENT_STACK16->mutex_count;
|
|
|
|
if (!count)
|
|
ERR(win32, "Win16Mutex recursion count is zero!\n");
|
|
|
|
TRACE(win32, "thread %04x (pid %d) about to restore (count %ld)\n",
|
|
THREAD_Current()->teb_sel, getpid(), count);
|
|
|
|
RestoreThunkLock(count);
|
|
|
|
TRACE(win32, "thread %04x (pid %d) restored lock, count is %ld\n",
|
|
THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
|
|
}
|
|
|