source: trunk/src/kernel32/wintls.cpp@ 7029

Last change on this file since 7029 was 4796, checked in by sandervl, 25 years ago

GetVolumeInformation bugfix + invalid VirtualFree calls corrected + free named shared memory

File size: 7.3 KB
Line 
1/* $Id: wintls.cpp,v 1.17 2000-12-12 23:57:16 sandervl Exp $ */
2/*
3 * Win32 TLS API functions
4 *
5 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
6 *
7 * TODO: correct errors set for Tls* apis? (verify in NT)
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#include <os2win.h>
13#include <string.h>
14#include <winimagebase.h>
15#include <thread.h>
16#include <wprocess.h>
17#include "exceptutil.h"
18
19#define DBG_LOCALLOG DBG_wintls
20#include "dbglocal.h"
21
22//******************************************************************************
23//******************************************************************************
24void Win32ImageBase::tlsAlloc() //Allocate TLS index for this module
25{
26 if(!tlsAddress)
27 return;
28
29 tlsIndex = TlsAlloc();
30 if(tlsIndex >= TLS_MINIMUM_AVAILABLE) {
31 dprintf(("tlsAlloc: invalid tlsIndex %x!!!!", tlsIndex));
32 DebugInt3();
33 return;
34 }
35 dprintf(("Win32ImageBase::tlsAlloc (%d) for module %x", tlsIndex, hinstance));
36}
37//******************************************************************************
38//******************************************************************************
39void Win32ImageBase::tlsDelete() //Free TLS index for this module
40{
41 if(!tlsAddress)
42 return;
43
44 if(tlsIndex >= TLS_MINIMUM_AVAILABLE) {
45 dprintf(("tlsDelete: invalid tlsIndex %x!!!!", tlsIndex));
46 DebugInt3();
47 return;
48 }
49 dprintf(("Win32ImageBase::tlsDestroy (%d) for module %x", tlsIndex, hinstance));
50 TlsFree(tlsIndex);
51 tlsIndex = -1;
52}
53//******************************************************************************
54//******************************************************************************
55void Win32ImageBase::tlsAttachThread() //setup TLS structures for new thread
56{
57 EXCEPTION_FRAME exceptFrame;
58 PIMAGE_TLS_CALLBACK *pCallback;
59 LPVOID tibmem;
60
61 if(!tlsAddress)
62 return;
63
64 if(tlsIndex >= TLS_MINIMUM_AVAILABLE) {
65 dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex));
66 DebugInt3();
67 return;
68 }
69
70 dprintf(("Win32ImageBase::tlsAttachThread for module %x, thread id %x", hinstance, GetCurrentThreadId()));
71 dprintf(("tlsAddress: %x", tlsAddress));
72 dprintf(("tlsInitSize: %x", tlsInitSize));
73 dprintf(("tlsTotalSize %x", tlsTotalSize));
74 dprintf(("tlsIndexAddr %x", tlsIndexAddr));
75 dprintf(("tlsCallbackAddr %x", tlsCallBackAddr));
76 dprintf(("*tlsCallbackAddr %x", (tlsCallBackAddr) ? *tlsCallBackAddr : 0));
77 tibmem = VirtualAlloc(0, tlsTotalSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
78 if(tibmem == NULL) {
79 dprintf(("tlsAttachThread: tibmem == NULL!!!!"));
80 DebugInt3();
81 return;
82 }
83 memset(tibmem, 0, tlsTotalSize);
84 memcpy(tibmem, tlsAddress, tlsInitSize);
85
86 TlsSetValue(tlsIndex, tibmem);
87 *tlsIndexAddr = tlsIndex;
88
89 if(tlsCallBackAddr && (ULONG)*tlsCallBackAddr != 0)
90 {
91 pCallback = tlsCallBackAddr;
92 while(*pCallback) {
93 dprintf(("tlsAttachThread: calling TLS Callback %x", *pCallback));
94
95 (*pCallback)((LPVOID)hinstance, DLL_THREAD_ATTACH, 0);
96
97 dprintf(("tlsAttachThread: finished calling TLS Callback %x", *pCallback));
98 pCallback++;
99 }
100 }
101 return;
102}
103//******************************************************************************
104//******************************************************************************
105void Win32ImageBase::tlsDetachThread() //destroy TLS structures
106{
107 EXCEPTION_FRAME exceptFrame;
108 PIMAGE_TLS_CALLBACK *pCallback;
109 LPVOID tlsmem;
110
111 if(!tlsAddress)
112 return;
113
114 dprintf(("Win32ImageBase::tlsDetachThread for module %x, thread id %x", hinstance, GetCurrentThreadId()));
115
116 if(tlsCallBackAddr && (ULONG)*tlsCallBackAddr != 0)
117 {
118 pCallback = tlsCallBackAddr;
119 while(*pCallback) {
120 dprintf(("tlsDetachThread: calling TLS Callback %x", *pCallback));
121
122 (*pCallback)((LPVOID)hinstance, DLL_THREAD_DETACH, 0);
123
124 dprintf(("tlsDetachThread: finished calling TLS Callback %x", *pCallback));
125 pCallback++;
126 }
127 }
128 tlsmem = TlsGetValue(tlsIndex);
129 if(tlsmem) {
130 VirtualFree(tlsmem, 0, MEM_RELEASE);
131 }
132 else {
133 dprintf(("ERROR: tlsDetachThread: tlsmem == NULL!!!"));
134 }
135 TlsFree(tlsIndex);
136}
137//******************************************************************************
138//******************************************************************************
139DWORD WIN32API TlsAlloc()
140{
141 DWORD index = -1;
142 TEB *teb;
143 PDB *pdb;
144 DWORD mask, tibidx;
145 int i;
146
147 teb = GetThreadTEB();
148 pdb = PROCESS_Current();
149
150 EnterCriticalSection(&pdb->crit_section);
151 tibidx = 0;
152 if(pdb->tls_bits[0] == 0xFFFFFFFF) {
153 if(pdb->tls_bits[1] == 0xFFFFFFFF) {
154 LeaveCriticalSection(&pdb->crit_section);
155 SetLastError(ERROR_NO_MORE_ITEMS); //TODO: correct error?
156 return -1;
157 }
158 tibidx = 1;
159 }
160 for(i=0;i<32;i++) {
161 mask = (1 << i);
162 if((pdb->tls_bits[tibidx] & mask) == 0) {
163 pdb->tls_bits[tibidx] |= mask;
164 index = (tibidx*32) + i;
165 break;
166 }
167 }
168 LeaveCriticalSection(&pdb->crit_section);
169 teb->tls_array[index] = 0;
170
171 dprintf(("KERNEL32: TlsAlloc returned %d", index));
172 return index;
173}
174//******************************************************************************
175//******************************************************************************
176BOOL WIN32API TlsFree(DWORD index)
177{
178 TEB *teb;
179 PDB *pdb;
180 int tlsidx;
181 DWORD mask;
182
183 dprintf(("KERNEL32: TlsFree %d", index));
184 if(index >= TLS_MINIMUM_AVAILABLE)
185 {
186 SetLastError(ERROR_INVALID_PARAMETER);
187 return NULL;
188 }
189
190 teb = GetThreadTEB();
191 pdb = PROCESS_Current();
192
193 EnterCriticalSection(&pdb->crit_section);
194 tlsidx = 0;
195 if(index > 32) {
196 tlsidx++;
197 }
198 mask = (1 << index);
199 if(pdb->tls_bits[tlsidx] & mask) {
200 LeaveCriticalSection(&pdb->crit_section);
201 pdb->tls_bits[tlsidx] &= ~mask;
202 teb->tls_array[index] = 0;
203 SetLastError(ERROR_SUCCESS);
204 return TRUE;
205 }
206 LeaveCriticalSection(&pdb->crit_section);
207 SetLastError(ERROR_INVALID_PARAMETER); //TODO: correct error? (does NT even change the last error?)
208 return FALSE;
209}
210//******************************************************************************
211//******************************************************************************
212LPVOID WIN32API TlsGetValue(DWORD index)
213{
214 LPVOID rc;
215 TEB *teb;
216
217 if(index >= TLS_MINIMUM_AVAILABLE)
218 {
219 SetLastError(ERROR_INVALID_PARAMETER);
220 return NULL;
221 }
222 SetLastError(ERROR_SUCCESS);
223
224 teb = GetThreadTEB();
225 rc = teb->tls_array[index];
226
227 dprintf2(("KERNEL32: TlsGetValue %d returned %X\n", index, rc));
228 return(rc);
229}
230//******************************************************************************
231//******************************************************************************
232BOOL WIN32API TlsSetValue(DWORD index, LPVOID val)
233{
234 TEB *teb;
235
236 dprintf2(("KERNEL32: TlsSetValue %d %x", index, val));
237 if(index >= TLS_MINIMUM_AVAILABLE)
238 {
239 SetLastError(ERROR_INVALID_PARAMETER);
240 return FALSE;
241 }
242 SetLastError(ERROR_SUCCESS);
243
244 teb = GetThreadTEB();
245 teb->tls_array[index] = val;
246 return TRUE;
247}
248//******************************************************************************
249//******************************************************************************
Note: See TracBrowser for help on using the repository browser.