2 * Win32 'syslevel' routines
4 * Copyright 1998 Ulrich Weigand
10 #include "stackframe.h"
13 DEFAULT_DEBUG_CHANNEL(win32
)
15 static CRITICAL_SECTION Win16Mutex
;
16 static SEGPTR segpWin16Mutex
;
18 /* Global variable to save current TEB while in 16-bit code */
19 WORD SYSLEVEL_Win16CurrentTeb
= 0;
21 /* TEB of initial process for emergency use */
22 WORD SYSLEVEL_EmergencyTeb
= 0;
25 /************************************************************************
28 void SYSLEVEL_Init(void)
30 CRITICAL_SECTION
**w16Mutex
= SEGPTR_ALLOC(sizeof(CRITICAL_SECTION
*));
32 *w16Mutex
= &Win16Mutex
;
33 segpWin16Mutex
= SEGPTR_GET(w16Mutex
);
35 InitializeCriticalSection(&Win16Mutex
);
36 MakeCriticalSectionGlobal(&Win16Mutex
);
39 /************************************************************************
40 * GetpWin16Lock32 (KERNEL32.93)
42 VOID WINAPI
GetpWin16Lock(CRITICAL_SECTION
**lock
)
47 /************************************************************************
48 * GetpWin16Lock16 (KERNEL.449)
50 SEGPTR WINAPI
GetpWin16Lock16(void)
52 return segpWin16Mutex
;
55 /************************************************************************
56 * _EnterSysLevel (KERNEL32.97)
58 VOID WINAPI
_EnterSysLevel(CRITICAL_SECTION
*lock
)
60 EnterCriticalSection(lock
);
62 if (lock
== &Win16Mutex
)
63 GET_FS( SYSLEVEL_Win16CurrentTeb
);
66 /************************************************************************
67 * _LeaveSysLevel (KERNEL32.98)
69 VOID WINAPI
_LeaveSysLevel(CRITICAL_SECTION
*lock
)
71 LeaveCriticalSection(lock
);
74 /************************************************************************
77 VOID WINAPI
_KERNEL32_86(CRITICAL_SECTION
*lock
)
82 /************************************************************************
83 * SYSLEVEL_EnterWin16Lock [KERNEL.480]
85 VOID WINAPI
SYSLEVEL_EnterWin16Lock(VOID
)
87 TRACE(win32
, "thread %04x (pid %d) about to enter\n",
88 THREAD_Current()->teb_sel
, getpid());
90 _EnterSysLevel(&Win16Mutex
);
92 TRACE(win32
, "thread %04x (pid %d) entered, count is %ld\n",
93 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);
96 /************************************************************************
97 * SYSLEVEL_LeaveWin16Lock [KERNEL.481]
99 VOID WINAPI
SYSLEVEL_LeaveWin16Lock(VOID
)
101 TRACE(win32
, "thread %04x (pid %d) about to leave, count is %ld\n",
102 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);
104 _LeaveSysLevel(&Win16Mutex
);
107 /************************************************************************
108 * _CheckNotSysLevel (KERNEL32.94)
110 VOID WINAPI
_CheckNotSysLevel(CRITICAL_SECTION
*lock
)
112 FIXME(win32
, "()\n");
115 /************************************************************************
116 * _ConfirmSysLevel (KERNEL32.95)
118 VOID WINAPI
_ConfirmSysLevel(CRITICAL_SECTION
*lock
)
120 FIXME(win32
, "()\n");
123 /************************************************************************
124 * _ConfirmWin16Lock (KERNEL32.96)
126 DWORD WINAPI
_ConfirmWin16Lock(void)
128 if ( Win16Mutex
.OwningThread
== GetCurrentThreadId() )
129 return Win16Mutex
.RecursionCount
;
134 /************************************************************************
135 * ReleaseThunkLock (KERNEL32.48)
137 VOID WINAPI
ReleaseThunkLock(DWORD
*mutex_count
)
139 DWORD count
= Win16Mutex
.RecursionCount
;
140 *mutex_count
= count
;
143 _LeaveSysLevel(&Win16Mutex
);
146 /************************************************************************
147 * RestoreThunkLock (KERNEL32.49)
149 VOID WINAPI
RestoreThunkLock(DWORD mutex_count
)
151 while (mutex_count
-- > 0)
152 _EnterSysLevel(&Win16Mutex
);
155 /************************************************************************
156 * SYSLEVEL_ReleaseWin16Lock
158 VOID
SYSLEVEL_ReleaseWin16Lock(VOID
)
162 TRACE(win32
, "thread %04x (pid %d) about to release, count is %ld\n",
163 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);
165 ReleaseThunkLock(&count
);
168 ERR(win32
, "Win16Mutex recursion count too large!\n");
170 CURRENT_STACK16
->mutex_count
= (WORD
)count
;
173 /************************************************************************
174 * SYSLEVEL_RestoreWin16Lock
176 VOID
SYSLEVEL_RestoreWin16Lock(VOID
)
178 DWORD count
= CURRENT_STACK16
->mutex_count
;
181 ERR(win32
, "Win16Mutex recursion count is zero!\n");
183 TRACE(win32
, "thread %04x (pid %d) about to restore (count %ld)\n",
184 THREAD_Current()->teb_sel
, getpid(), count
);
186 RestoreThunkLock(count
);
188 TRACE(win32
, "thread %04x (pid %d) restored lock, count is %ld\n",
189 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);