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;
20 /************************************************************************
23 void SYSLEVEL_Init(void)
25 CRITICAL_SECTION
**w16Mutex
= SEGPTR_ALLOC(sizeof(CRITICAL_SECTION
*));
27 *w16Mutex
= &Win16Mutex
;
28 segpWin16Mutex
= SEGPTR_GET(w16Mutex
);
30 InitializeCriticalSection(&Win16Mutex
);
33 /************************************************************************
34 * GetpWin16Lock32 (KERNEL32.93)
36 VOID WINAPI
GetpWin16Lock32(CRITICAL_SECTION
**lock
)
41 /************************************************************************
42 * GetpWin16Lock16 (KERNEL.449)
44 SEGPTR WINAPI
GetpWin16Lock16(void)
46 return segpWin16Mutex
;
49 /************************************************************************
50 * _EnterSysLevel (KERNEL32.97)
52 VOID WINAPI
_EnterSysLevel(CRITICAL_SECTION
*lock
)
54 EnterCriticalSection(lock
);
56 if (lock
== &Win16Mutex
)
57 GET_FS( SYSLEVEL_Win16CurrentTeb
);
60 /************************************************************************
61 * _LeaveSysLevel (KERNEL32.98)
63 VOID WINAPI
_LeaveSysLevel(CRITICAL_SECTION
*lock
)
65 LeaveCriticalSection(lock
);
68 /************************************************************************
71 VOID WINAPI
_KERNEL32_86(CRITICAL_SECTION
*lock
)
76 /************************************************************************
77 * SYSLEVEL_EnterWin16Lock
79 VOID
SYSLEVEL_EnterWin16Lock(VOID
)
81 TRACE(win32
, "thread %04x (pid %d) about to enter\n",
82 THREAD_Current()->teb_sel
, getpid());
84 _EnterSysLevel(&Win16Mutex
);
86 TRACE(win32
, "thread %04x (pid %d) entered, count is %ld\n",
87 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);
90 /************************************************************************
91 * SYSLEVEL_LeaveWin16Lock
93 VOID
SYSLEVEL_LeaveWin16Lock(VOID
)
95 TRACE(win32
, "thread %04x (pid %d) about to leave, count is %ld\n",
96 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);
98 _LeaveSysLevel(&Win16Mutex
);
101 /************************************************************************
102 * _CheckNotSysLevel (KERNEL32.94)
104 VOID WINAPI
_CheckNotSysLevel(CRITICAL_SECTION
*lock
)
106 FIXME(win32
, "()\n");
109 /************************************************************************
110 * _ConfirmSysLevel (KERNEL32.95)
112 VOID WINAPI
_ConfirmSysLevel(CRITICAL_SECTION
*lock
)
114 FIXME(win32
, "()\n");
117 /************************************************************************
118 * _ConfirmWin16Lock (KERNEL32.96)
120 DWORD WINAPI
_ConfirmWin16Lock(void)
122 FIXME(win32
, "()\n");
126 /************************************************************************
127 * ReleaseThunkLock (KERNEL32.48)
129 VOID WINAPI
ReleaseThunkLock(DWORD
*mutex_count
)
131 DWORD count
= Win16Mutex
.RecursionCount
;
132 *mutex_count
= count
;
135 _LeaveSysLevel(&Win16Mutex
);
138 /************************************************************************
139 * RestoreThunkLock (KERNEL32.49)
141 VOID WINAPI
RestoreThunkLock(DWORD mutex_count
)
143 while (mutex_count
-- > 0)
144 _EnterSysLevel(&Win16Mutex
);
147 /************************************************************************
148 * SYSLEVEL_ReleaseWin16Lock
150 VOID
SYSLEVEL_ReleaseWin16Lock(VOID
)
154 TRACE(win32
, "thread %04x (pid %d) about to release, count is %ld\n",
155 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);
157 ReleaseThunkLock(&count
);
160 ERR(win32
, "Win16Mutex recursion count too large!\n");
162 CURRENT_STACK16
->mutex_count
= (WORD
)count
;
165 /************************************************************************
166 * SYSLEVEL_RestoreWin16Lock
168 VOID
SYSLEVEL_RestoreWin16Lock(VOID
)
170 DWORD count
= CURRENT_STACK16
->mutex_count
;
173 ERR(win32
, "Win16Mutex recursion count is zero!\n");
175 TRACE(win32
, "thread %04x (pid %d) about to restore (count %ld)\n",
176 THREAD_Current()->teb_sel
, getpid(), count
);
178 RestoreThunkLock(count
);
180 TRACE(win32
, "thread %04x (pid %d) restored lock, count is %ld\n",
181 THREAD_Current()->teb_sel
, getpid(), Win16Mutex
.RecursionCount
);