2 * Win32 'syslevel' routines
4 * Copyright 1998 Ulrich Weigand
10 #include "stackframe.h"
13 static CRITICAL_SECTION Win16Mutex
;
14 static SEGPTR segpWin16Mutex
;
16 /* Global variable to save current TEB while in 16-bit code */
17 WORD SYSLEVEL_Win16CurrentTeb
= 0;
19 /* TEB of initial process for emergency use */
20 WORD SYSLEVEL_EmergencyTeb
= 0;
23 /************************************************************************
26 void SYSLEVEL_Init(void)
28 CRITICAL_SECTION
**w16Mutex
= SEGPTR_ALLOC(sizeof(CRITICAL_SECTION
*));
30 *w16Mutex
= &Win16Mutex
;
31 segpWin16Mutex
= SEGPTR_GET(w16Mutex
);
33 InitializeCriticalSection(&Win16Mutex
);
34 MakeCriticalSectionGlobal(&Win16Mutex
);
37 /************************************************************************
38 * GetpWin16Lock32 (KERNEL32.93)
40 VOID WINAPI
GetpWin16Lock(CRITICAL_SECTION
**lock
)
45 /************************************************************************
46 * GetpWin16Lock16 (KERNEL.449)
48 SEGPTR WINAPI
GetpWin16Lock16(void)
50 return segpWin16Mutex
;
53 /************************************************************************
54 * _EnterSysLevel (KERNEL32.97)
56 VOID WINAPI
_EnterSysLevel(CRITICAL_SECTION
*lock
)
58 EnterCriticalSection(lock
);
60 if (lock
== &Win16Mutex
)
61 GET_FS( SYSLEVEL_Win16CurrentTeb
);
64 /************************************************************************
65 * _LeaveSysLevel (KERNEL32.98)
67 VOID WINAPI
_LeaveSysLevel(CRITICAL_SECTION
*lock
)
69 LeaveCriticalSection(lock
);
72 /************************************************************************
75 VOID WINAPI
_KERNEL32_86(CRITICAL_SECTION
*lock
)
80 /************************************************************************
81 * SYSLEVEL_EnterWin16Lock [KERNEL.480]
83 VOID WINAPI
SYSLEVEL_EnterWin16Lock(VOID
)
85 TRACE(win32
, "thread %04x (pid %d) about to enter\n",
86 THREAD_Current()->teb_sel
, getpid());
88 _EnterSysLevel(&Win16Mutex
);
90 TRACE(win32
, "thread %04x (pid %d) entered, count is %ld\n",
91 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);
94 /************************************************************************
95 * SYSLEVEL_LeaveWin16Lock [KERNEL.481]
97 VOID WINAPI
SYSLEVEL_LeaveWin16Lock(VOID
)
99 TRACE(win32
, "thread %04x (pid %d) about to leave, count is %ld\n",
100 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);
102 _LeaveSysLevel(&Win16Mutex
);
105 /************************************************************************
106 * _CheckNotSysLevel (KERNEL32.94)
108 VOID WINAPI
_CheckNotSysLevel(CRITICAL_SECTION
*lock
)
110 FIXME(win32
, "()\n");
113 /************************************************************************
114 * _ConfirmSysLevel (KERNEL32.95)
116 VOID WINAPI
_ConfirmSysLevel(CRITICAL_SECTION
*lock
)
118 FIXME(win32
, "()\n");
121 /************************************************************************
122 * _ConfirmWin16Lock (KERNEL32.96)
124 DWORD WINAPI
_ConfirmWin16Lock(void)
126 FIXME(win32
, "()\n");
130 /************************************************************************
131 * ReleaseThunkLock (KERNEL32.48)
133 VOID WINAPI
ReleaseThunkLock(DWORD
*mutex_count
)
135 DWORD count
= Win16Mutex
.RecursionCount
;
136 *mutex_count
= count
;
139 _LeaveSysLevel(&Win16Mutex
);
142 /************************************************************************
143 * RestoreThunkLock (KERNEL32.49)
145 VOID WINAPI
RestoreThunkLock(DWORD mutex_count
)
147 while (mutex_count
-- > 0)
148 _EnterSysLevel(&Win16Mutex
);
151 /************************************************************************
152 * SYSLEVEL_ReleaseWin16Lock
154 VOID
SYSLEVEL_ReleaseWin16Lock(VOID
)
158 TRACE(win32
, "thread %04x (pid %d) about to release, count is %ld\n",
159 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);
161 ReleaseThunkLock(&count
);
164 ERR(win32
, "Win16Mutex recursion count too large!\n");
166 CURRENT_STACK16
->mutex_count
= (WORD
)count
;
169 /************************************************************************
170 * SYSLEVEL_RestoreWin16Lock
172 VOID
SYSLEVEL_RestoreWin16Lock(VOID
)
174 DWORD count
= CURRENT_STACK16
->mutex_count
;
177 ERR(win32
, "Win16Mutex recursion count is zero!\n");
179 TRACE(win32
, "thread %04x (pid %d) about to restore (count %ld)\n",
180 THREAD_Current()->teb_sel
, getpid(), count
);
182 RestoreThunkLock(count
);
184 TRACE(win32
, "thread %04x (pid %d) restored lock, count is %ld\n",
185 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);