- Timestamp:
- Sep 21, 2000, 9:44:32 PM (25 years ago)
- Location:
- trunk/src/kernel32
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/iccio.asm
r4296 r4298 1 ; $Id: iccio.asm,v 1. 6 2000-09-21 18:24:32 hughExp $1 ; $Id: iccio.asm,v 1.7 2000-09-21 19:44:32 sandervl Exp $ 2 2 3 3 ; ********************************************************************** … … 10 10 ; compile with ALP 11 11 ; 12 TITLE ICCIO.ASM 13 .386 14 .387 15 CODE32 SEGMENT DWORD USE32 PUBLIC 'CODE' 16 CODE32 ENDS 17 DATA32 SEGMENT DWORD USE32 PUBLIC 'DATA' 12 TITLE ICCIO.ASM 13 .386 14 .387 15 16 DATA32 SEGMENT DWORD PUBLIC USE32 'DATA' 17 ; ASSUME CS:FLAT ,DS:FLAT,SS:FLAT 18 ASSUME DS:FLAT,SS:FLAT 19 EXTRN ioentry:DWORD 20 EXTRN gdt:WORD 21 EXTRN devname:BYTE 18 22 DATA32 ENDS 19 CONST32 SEGMENT DWORD USE32 PUBLIC 'CONST' 20 CONST32 ENDS 21 BSS32 SEGMENT DWORD USE32 PUBLIC 'BSS' 22 BSS32 ENDS 23 DGROUP GROUP CONST32, BSS32, DATA32 24 ASSUME CS:FLAT, DS:FLAT, SS:FLAT, ES:FLAT 25 DATA32 SEGMENT 26 DATA32 ENDS 27 BSS32 SEGMENT 28 BSS32 ENDS 29 CONST32 SEGMENT 30 CONST32 ENDS 31 32 DATA32 SEGMENT 33 ioentry DWORD 0 34 gdt WORD 0 35 DATA32 ENDS 36 37 CODE32 SEGMENT 23 24 CODE32 SEGMENT DWORD PUBLIC USE32 'CODE' 25 ; ASSUME CS:FLAT ,DS:FLAT,SS:FLAT 26 ASSUME DS:FLAT,SS:FLAT 27 28 ALIGN 04H 38 29 39 30 ; performs fast output of a byte to an I/O port 40 ; this routine is intended to be called from gcc C code 41 ; 42 ; Calling convention: 43 ; void c_outb1(short port,char data) 44 ; 45 ; 46 PUBLIC c_outb 47 ALIGN 04H 48 c_outb PROC 49 MOV EDX, [ESP+4] ; get port 50 MOV AL, [ESP+8] ; get data 51 OUT DX,AL 52 RET 53 c_outb ENDP 31 ; this routine is intended to be called from icc C code 32 ; 33 ; Calling convention: 34 ; void _c_outb(short port,char data) 35 ; 36 ; 37 PUBLIC _c_outb 38 _c_outb PROC 39 MOV EDX, DWORD PTR [ESP+4] ; get port 40 MOV AL, BYTE PTR [ESP+8] ; get data 41 PUSH EBX ; save register 42 MOV EBX, 4 ; function code 4 = write byte 43 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 44 POP EBX 45 RET 46 _c_outb ENDP 54 47 55 48 ; performs fast output of a word to an I/O port 56 ; this routine is intended to be called from gcc C code 57 ; 58 ; Calling convention: 59 ; void c_outw1(short port,short data) 60 ; 61 ; 62 PUBLIC c_outw 63 ALIGN 04H 64 c_outw PROC 65 MOV EDX, [ESP+4] ; get port 66 MOV AX, [ESP+8] ; get data 67 OUT DX,AX 68 RET 69 c_outw ENDP 70 71 ; performs fast output of a longword to an I/O port 72 ; this routine is intended to be called from gcc C code 73 ; 74 ; Calling convention: 75 ; void c_outl1(short port,long data) 76 ; 77 ; 78 PUBLIC c_outl 79 ALIGN 04H 80 c_outl PROC 81 MOV EDX, [ESP+4] ; get port 82 MOV EAX, [ESP+8] ; get data 83 OUT DX, EAX 84 RET 85 c_outl ENDP 49 ; this routine is intended to be called from icc C code 50 ; 51 ; Calling convention: 52 ; void _c_outw(short port,short data) 53 ; 54 ; 55 ALIGN 04H 56 57 PUBLIC _c_outw 58 _c_outw PROC 59 MOV EDX, DWORD PTR [ESP+4] ; get port 60 MOV AX, WORD PTR [ESP+8] ; get data 61 PUSH EBX ; save register 62 MOV EBX, 5 ; function code 5 = write word 63 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 64 POP EBX 65 RET 66 _c_outw ENDP 67 68 ; performs fast output of a dword to an I/O port 69 ; this routine is intended to be called from icc C code 70 ; 71 ; Calling convention: 72 ; void _c_outl(short port,long data) 73 ; 74 ; 75 ALIGN 04H 76 77 PUBLIC _c_outl 78 _c_outl PROC 79 MOV EDX, DWORD PTR [ESP+4] ; get port 80 MOV EAX, DWORD PTR [ESP+8] ; get data 81 PUSH EBX ; save register 82 MOV EBX, 6 ; function code 6 = write dword 83 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 84 POP EBX 85 RET 86 _c_outl ENDP 86 87 87 88 ; performs fast input of a byte from an I/O port … … 89 90 ; 90 91 ; Calling convention: 91 ; char c_inb1(short port) 92 ; 93 ; 94 PUBLIC c_inb 95 ALIGN 04H 96 c_inb PROC 97 MOV EDX, [ESP+4] ; get port 98 IN AL,DX 99 AND EAX, 000000FFh 100 RET 101 c_inb ENDP 92 ; char _c_inb(short port) 93 ; 94 ; 95 ALIGN 04H 96 PUBLIC _c_inb 97 _c_inb PROC 98 MOV EDX, DWORD PTR [ESP+4] ; get port number 99 PUSH EBX ; save register 100 MOV EBX, 1 ; function code 1 = read byte 101 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 102 AND EAX, 000000ffH ; mask out required byte 103 POP EBX ; restore register 104 RET 105 _c_inb ENDP 102 106 103 107 ; performs fast input of a word from an I/O port … … 105 109 ; 106 110 ; Calling convention: 107 ; short c_inw1(short port) 108 ; 109 ; 110 PUBLIC c_inw 111 ALIGN 04H 112 c_inw PROC 113 MOV EDX, [ESP+4] ; get port 114 IN AX, DX 115 AND EAX, 0000FFFFh ; mask out word 116 RET 117 c_inw ENDP 118 119 ; performs fast input of a longword from an I/O port 111 ; short _c_inw(short port) 112 ; 113 ; 114 ALIGN 04H 115 PUBLIC _c_inw 116 _c_inw PROC 117 MOV EDX, DWORD PTR [ESP+4] ; get port number 118 PUSH EBX ; save register 119 MOV EBX, 2 ; function code 2 = read short 120 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 121 AND EAX, 0000ffffH ; mask out required byte 122 POP EBX ; restore register 123 RET 124 _c_inw ENDP 125 126 ; performs fast input of a dword from an I/O port 120 127 ; this routine is intended to be called from gcc C code 121 128 ; 122 129 ; Calling convention: 123 ; lomg c_inl1(short port) 124 ; 125 ; 126 PUBLIC c_inl 127 ALIGN 04H 128 c_inl PROC 129 MOV EDX, [ESP+4] ; get port 130 IN EAX, DX 131 RET 132 c_inl ENDP 130 ; long _c_inl(short port) 131 ; 132 ; 133 ALIGN 04H 134 PUBLIC _c_inl 135 _c_inl PROC 136 MOV EDX, DWORD PTR [ESP+4] ; get port number 137 PUSH EBX ; save register 138 MOV EBX, 3 ; function code 3 = read long 139 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 140 ; AND EAX, 000000ffH ; mask out required byte 141 POP EBX ; restore register 142 RET 143 _c_inl ENDP 144 145 ALIGN 4 146 PUBLIC _c_readmsr 147 _c_readmsr PROC NEAR 148 PUSH EBP 149 MOV EBP, ESP 150 PUSH EAX 151 PUSH EBX 152 PUSH ECX 153 PUSH EDX ; save register 154 MOV ECX, DWORD PTR [EBP+8] ; get msr reg 155 MOV EBX, 7 ; function code 7 = read msr 156 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 157 MOV EBX, DWORD PTR [EBP+12] ; LONGLONG ptr 158 MOV DWORD PTR [EBX+4], EDX 159 MOV DWORD PTR [EBX], EAX 160 POP EDX 161 POP ECX 162 POP EBX ; restore register 163 POP EAX 164 POP EBP 165 RET 166 _c_readmsr ENDP 167 168 ;------------------------------------------------------------------------------ 169 170 ; performs fast output of a byte to an I/O port 171 ; this routine is intended to be called from assembler code 172 ; note there is no stack frame, however 8 byte stack space is required 173 ; 174 ; calling convention: 175 ; MOV EDX, portnr 176 ; MOV AL, data 177 ; CALL a_outb 178 ; 179 ; 180 ALIGN 04H 181 PUBLIC a_outb 182 a_outb PROC 183 PUSH EBX ; save register 184 MOV EBX, 4 ; function code 4 = write byte 185 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 186 POP EBX ; restore bx 187 RET 188 a_outb ENDP 189 190 ; performs fast output of a word to an I/O port 191 ; this routine is intended to be called from assembler code 192 ; note there is no stack frame, however 8 byte stack space is required 193 ; 194 ; calling convention: 195 ; MOV EDX, portnr 196 ; MOV AX, data 197 ; CALL a_outw 198 ; 199 ; 200 ALIGN 04H 201 PUBLIC a_outw 202 a_outw PROC 203 PUSH EBX ; save register 204 MOV EBX, 5 ; function code 5 = write word 205 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 206 POP EBX ; restore bx 207 RET 208 a_outw ENDP 209 210 ; performs fast output of a long to an I/O port 211 ; this routine is intended to be called from assembler code 212 ; note there is no stack frame, however 8 byte stack space is required 213 ; 214 ; calling convention: 215 ; MOV EDX, portnr 216 ; MOV EAX, data 217 ; CALL a_outl 218 ; 219 ; 220 ALIGN 04H 221 PUBLIC a_outl 222 a_outl PROC 223 PUSH EBX ; save register 224 MOV EBX, 6 ; function code 6 = write long 225 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 226 POP EBX ; restore bx 227 RET 228 a_outl ENDP 229 230 ; performs fast input of a byte from an I/O port 231 ; this routine is intended to be called from assembler code 232 ; note there is no stack frame, however 8 byte stack space is required 233 ; 234 ; calling convention: 235 ; MOV EDX, portnr 236 ; CALL a_inb 237 ; ;data in AL 238 ; 239 ALIGN 04H 240 PUBLIC a_inb 241 a_inb PROC 242 PUSH EBX ; save register 243 MOV EBX, 1 ; function code 1 = read byte 244 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 245 AND EAX, 000000FFh ; mask byte 246 POP EBX ; restore register 247 RET 248 a_inb ENDP 249 250 251 ; performs fast input of a word from an I/O port 252 ; this routine is intended to be called from assembler code 253 ; note there is no stack frame, however 8 byte stack space is required 254 ; 255 ; calling convention: 256 ; MOV EDX, portnr 257 ; CALL a_inb 258 ; ;data in AX 259 ; 260 ALIGN 04H 261 PUBLIC a_inw 262 a_inw PROC 263 PUSH EBX ; save register 264 MOV EBX, 2 ; function code 2 = read word 265 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 266 AND EAX, 0000FFFFh ; mask byte 267 POP EBX ; restore register 268 RET 269 a_inw ENDP 270 271 ; performs fast input of a dword from an I/O port 272 ; this routine is intended to be called from assembler code 273 ; note there is no stack frame, however 8 byte stack space is required 274 ; 275 ; calling convention: 276 ; MOV EDX, portnr 277 ; CALL a_inl 278 ; ;data in EAX 279 ; 280 ALIGN 04H 281 PUBLIC a_inl 282 a_inl PROC 283 PUSH EBX ; save register 284 MOV EBX, 3 ; function code 3 = read dword 285 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 286 POP EBX ; restore register 287 RET 288 a_inl ENDP 133 289 134 290 CODE32 ENDS … … 137 293 138 294 ; Initialize I/O access via the driver. 139 ; You *must* call this routine once for each *thread*that wants to do295 ; You *must* call this routine once for each executable that wants to do 140 296 ; I/O. 141 297 ; 142 298 ; The routine is mainly equivalent to a C routine performing the 143 299 ; following (but no need to add another file): 144 ; DosOpen("/dev/fastio$", read, nonexclusive)145 ; DosDevIOCtl(device, XFREE86IO, IOGETSEL32)146 ; selector -> ioentry+4147 ; DosClose(device)148 ; 149 ; Calling convention: 150 ; int io_init1(void)300 ; DosOpen("/dev/fastio$", read, nonexclusive) 301 ; DosDevIOCtl(device, XFREE86_IO, IO_GETSEL32) 302 ; selector -> ioentry+4 303 ; DosClose(device) 304 ; 305 ; Calling convention: 306 ; int io_init(void) 151 307 ; Return: 152 ; 0 if successful 153 ; standard APIRET RETurn code if error 154 ; 155 156 CONST32 SEGMENT 157 ALIGN 04H 158 devname: 159 DB "/dev/fastio$",0 160 CONST32 ENDS 161 308 ; 0 if successful 309 ; standard APIRET return code if error 310 ; 162 311 163 312 CODE32 SEGMENT 164 PUBLIC io_init1313 PUBLIC _io_init 165 314 EXTRN DosOpen:PROC 166 315 EXTRN DosClose:PROC 167 316 EXTRN DosDevIOCtl:PROC 168 io_init1PROC317 _io_init PROC 169 318 PUSH EBP 170 319 MOV EBP, ESP ; standard stack frame … … 193 342 ALIGN 04H 194 343 goon: 195 LEA EAX, [EBP-16]; address of 'len' arg of DosDevIOCtl196 PUSHEAX197 PUSH 2; sizeof(short)198 LEA EAX, [EBP-2]; address to return the GDT selector199 PUSHEAX200 PUSH 0; no parameter len201 PUSH 0; no parameter size202 PUSH 0; no parameter address203 PUSH 100 ; function code IOGETSEL32204 PUSH 118 ; category code XFREE6IO205 MOV EAX,[EBP-8]; file handle206 PUSHEAX207 CALL DosDevIOCtl; perform ioctl208 ADD ESP, 36; cleanup stack209 CMP EAX, 0; is return code = 0?210 JE ok; yes, proceed211 PUSH EAX; was error, save error code212 MOV EAX, [EBP-8]; file handle213 PUSHEAX214 CALL DosClose; close device215 ADD ESP,4; clean stack216 POP EAX; get error code217 LEAVE; return error218 RET219 220 ALIGN04H344 LEA EAX, [EBP-16] ; address of 'len' arg of DosDevIOCtl 345 PUSH EAX 346 PUSH 2 ; sizeof(short) 347 LEA EAX, [EBP-2] ; address to return the GDT selector 348 PUSH EAX 349 PUSH 0 ; no parameter len 350 PUSH 0 ; no parameter size 351 PUSH 0 ; no parameter address 352 PUSH 100 ; function code IO_GETSEL32 353 PUSH 118 ; category code XFREE6_IO 354 MOV EAX, [EBP-8] ; file handle 355 PUSH EAX 356 CALL DosDevIOCtl ; perform ioctl 357 ADD ESP, 36 ; cleanup stack 358 CMP EAX, 0 ; is return code = 0? 359 JE ok ; yes, proceed 360 PUSH EAX ; was error, save error code 361 MOV EAX, [EBP-8] ; file handle 362 PUSH EAX 363 CALL DosClose ; close device 364 ADD ESP, 4 ; clean stack 365 POP EAX ; get error code 366 LEAVE ; return error 367 RET 368 369 ALIGN 04H 221 370 ok: 222 MOV EAX, [EBP-8] ; file handle 223 PUSH EAX ; do normal close 224 CALL DosClose 225 ADD ESP,4 ; clean stack 226 227 MOV AX, [EBP-2] ; load gdt selector 228 MOV gdt, AX ; store in ioentry address selector part 229 XOR EAX, EAX ; EAX = 0 230 MOV DWORD PTR [ioentry], EAX ; clear ioentry offset part 231 ; return code = 0 (in EAX) 232 233 ; now use this function to raise the IOPL 234 MOV EBX,13 ; special function code 235 CALL FWORD PTR [ioentry] ; CALL intersegment indirect 16:32 236 237 ; thread should now be running at IOPL=3 238 239 XOR EAX, EAX ; return code = 0 240 LEAVE ; clean stack frame 241 RET ; exit 242 io_init1 ENDP 243 244 ; void in_init(short) 245 PUBLIC io_init2 246 ALIGN 04H 247 io_init2 PROC 248 249 MOV gdt, AX ; store in ioentry address selector part 250 XOR EAX, EAX ; EAX = 0 251 MOV DWORD PTR [ioentry], EAX ; clear ioentry offset part 252 ; return code = 0 (in EAX) 253 254 ; now use this function to raise the IOPL 255 MOV EBX,13 ; special function code 256 CALL FWORD PTR [ioentry] ; CALL intersegment indirect 16:32 257 258 XOR EAX, EAX ; return code = 0 259 ret 260 io_init2 ENDP 261 262 PUBLIC io_exit1 263 ALIGN 04H 264 io_exit1 PROC 265 push EBP 266 MOV EBP, ESP ; stackframe, I am accustomed to this :-) 267 268 MOV AX, gdt ; check if ioinit was called once 269 OR AX, AX 270 JZ exerr ; no gdt entry, so process cannot be at IOPL=3 271 ; through this mechanism 272 273 MOV EBX, 14 ; function code to disable iopl 274 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 275 276 ; process should now be at IOPL=3 again 277 XOR EAX, EAX ; ok, RETurn code = 0 278 LEAVE 279 RET 280 exerr: XOR EAX, EAX ; not ok, RETurn code = ffffffff 281 DEC EAX 282 LEAVE 283 RET 284 io_exit1 ENDP 285 371 MOV EAX,[EBP-8] ; file handle 372 PUSH EAX ; do normal close 373 CALL DosClose 374 ADD ESP, 4 ; clean stack 375 376 MOV AX, WORD PTR [EBP-2] ; load gdt selector 377 MOV gdt, AX ; store in ioentry address selector part 378 XOR EAX, EAX ; eax = 0 379 MOV DWORD PTR [ioentry], EAX ; clear ioentry offset part 380 ; return code = 0 (in %eax) 381 LEAVE ; clean stack frame 382 RET ; exit 383 _io_init ENDP 384 385 ; just for symmetry, does nothing 386 387 ALIGN 04H 388 PUBLIC _io_exit 389 _io_exit PROC 390 XOR EAX,EAX 391 RET 392 _io_exit ENDP 393 394 ALIGN 04H 395 PUBLIC int03 396 397 int03 PROC 398 INT 3 399 RET 400 int03 ENDP 401 402 ;------------------------------------------------------------------------------ 403 404 ; Initialize I/O access via the driver. 405 ; You *must* call this routine once for each *thread* that wants to do 406 ; I/O. 407 ; 408 ; The routine is mainly equivalent to a C routine performing the 409 ; following (but no need to add another file): 410 ; DosOpen("/dev/fastio$", read, nonexclusive) 411 ; DosDevIOCtl(device, XFREE86IO, IOGETSEL32) 412 ; selector -> ioentry+4 413 ; DosClose(device) 414 ; 415 ; Calling convention: 416 ; int io_init1(void) 417 ; Return: 418 ; 0 if successful 419 ; standard APIRET RETurn code if error 420 ; 286 421 287 422 PUBLIC _io_init1 … … 388 523 ; for diagnostic only 389 524 390 PUBLIC psw391 ALIGN04H392 psw 393 PUSHF; get the current PSW394 POP EAX; into EAX395 RET396 psw 525 PUBLIC psw 526 ALIGN 04H 527 psw PROC 528 PUSHF ; get the current PSW 529 POP EAX ; into EAX 530 RET 531 psw ENDP 397 532 398 533 CODE32 ENDS 399 END534 END -
trunk/src/kernel32/wintls.cpp
r4285 r4298 1 /* $Id: wintls.cpp,v 1.1 2 2000-09-20 21:32:54 hughExp $ */1 /* $Id: wintls.cpp,v 1.13 2000-09-21 19:39:57 sandervl Exp $ */ 2 2 /* 3 3 * Win32 TLS API functions … … 25 25 { 26 26 if(!tlsAddress) 27 return;27 return; 28 28 29 29 tlsIndex = TlsAlloc(); 30 30 if(tlsIndex >= TLS_MINIMUM_AVAILABLE) { 31 dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex));32 DebugInt3();33 return;31 dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex)); 32 DebugInt3(); 33 return; 34 34 } 35 35 dprintf(("Win32ImageBase::tlsAlloc (%d) for module %x", tlsIndex, hinstance)); … … 40 40 { 41 41 if(!tlsAddress) 42 return;42 return; 43 43 44 44 if(tlsIndex >= TLS_MINIMUM_AVAILABLE) { 45 dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex));46 DebugInt3();47 return;45 dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex)); 46 DebugInt3(); 47 return; 48 48 } 49 49 dprintf(("Win32ImageBase::tlsDestroy (%d) for module %x", tlsIndex, hinstance)); … … 60 60 61 61 if(!tlsAddress) 62 return;62 return; 63 63 64 64 if(tlsIndex >= TLS_MINIMUM_AVAILABLE) { 65 dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex));66 DebugInt3();67 return;65 dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex)); 66 DebugInt3(); 67 return; 68 68 } 69 69 … … 77 77 tibmem = VirtualAlloc(0, tlsTotalSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); 78 78 if(tibmem == NULL) { 79 dprintf(("tlsAttachThread: tibmem == NULL!!!!"));80 DebugInt3();81 return;79 dprintf(("tlsAttachThread: tibmem == NULL!!!!")); 80 DebugInt3(); 81 return; 82 82 } 83 83 memset(tibmem, 0, tlsTotalSize); … … 88 88 89 89 if(tlsCallBackAddr && (ULONG)*tlsCallBackAddr != 0) { 90 pCallback = tlsCallBackAddr;91 while(*pCallback) {92 dprintf(("tlsAttachThread: calling TLS Callback %x", *pCallback));93 94 (*pCallback)((LPVOID)hinstance, DLL_THREAD_ATTACH, 0);95 96 dprintf(("tlsAttachThread: finished calling TLS Callback %x", *pCallback));97 *pCallback++;98 }90 pCallback = tlsCallBackAddr; 91 while(*pCallback) { 92 dprintf(("tlsAttachThread: calling TLS Callback %x", *pCallback)); 93 94 (*pCallback)((LPVOID)hinstance, DLL_THREAD_ATTACH, 0); 95 96 dprintf(("tlsAttachThread: finished calling TLS Callback %x", *pCallback)); 97 *pCallback++; 98 } 99 99 } 100 100 return; … … 109 109 110 110 if(!tlsAddress) 111 return;111 return; 112 112 113 113 dprintf(("Win32ImageBase::tlsDetachThread for module %x, thread id %x", hinstance, GetCurrentThreadId())); 114 114 115 115 if(tlsCallBackAddr && (ULONG)*tlsCallBackAddr != 0) { 116 pCallback = tlsCallBackAddr;117 while(*pCallback) {118 dprintf(("tlsDetachThread: calling TLS Callback %x", *pCallback));119 120 (*pCallback)((LPVOID)hinstance, DLL_THREAD_DETACH, 0);121 122 dprintf(("tlsDetachThread: finished calling TLS Callback %x", *pCallback));123 *pCallback++;124 }116 pCallback = tlsCallBackAddr; 117 while(*pCallback) { 118 dprintf(("tlsDetachThread: calling TLS Callback %x", *pCallback)); 119 120 (*pCallback)((LPVOID)hinstance, DLL_THREAD_DETACH, 0); 121 122 dprintf(("tlsDetachThread: finished calling TLS Callback %x", *pCallback)); 123 *pCallback++; 124 } 125 125 } 126 126 tlsmem = TlsGetValue(tlsIndex); 127 127 if(tlsmem) { 128 VirtualFree(tlsmem, tlsTotalSize, MEM_RELEASE);128 VirtualFree(tlsmem, tlsTotalSize, MEM_RELEASE); 129 129 } 130 130 else { 131 dprintf(("ERROR: tlsDetachThread: tlsmem == NULL!!!"));131 dprintf(("ERROR: tlsDetachThread: tlsmem == NULL!!!")); 132 132 } 133 133 TlsFree(tlsIndex); … … 154 154 tibidx = 0; 155 155 if(pdb->tls_bits[0] == 0xFFFFFFFF) { 156 if(pdb->tls_bits[1] == 0xFFFFFFFF) {157 LeaveCriticalSection(&pdb->crit_section);158 SetLastError(ERROR_NO_MORE_ITEMS); //TODO: correct error?159 return -1;160 }161 tibidx = 1;156 if(pdb->tls_bits[1] == 0xFFFFFFFF) { 157 LeaveCriticalSection(&pdb->crit_section); 158 SetLastError(ERROR_NO_MORE_ITEMS); //TODO: correct error? 159 return -1; 160 } 161 tibidx = 1; 162 162 } 163 163 for(i=0;i<32;i++) { 164 mask = (1 << i);165 if((pdb->tls_bits[tibidx] & mask) == 0) {166 pdb->tls_bits[tibidx] |= mask;167 index = (tibidx*32) + i;168 break;169 }164 mask = (1 << i); 165 if((pdb->tls_bits[tibidx] & mask) == 0) { 166 pdb->tls_bits[tibidx] |= mask; 167 index = (tibidx*32) + i; 168 break; 169 } 170 170 } 171 171 LeaveCriticalSection(&pdb->crit_section); … … 205 205 if(pdb->tls_bits[tlsidx] & mask) { 206 206 LeaveCriticalSection(&pdb->crit_section); 207 pdb->tls_bits[tlsidx] &= ~mask;207 pdb->tls_bits[tlsidx] &= ~mask; 208 208 thdb->tls_array[index] = 0; 209 209 SetLastError(ERROR_SUCCESS); 210 return TRUE;210 return TRUE; 211 211 } 212 212 LeaveCriticalSection(&pdb->crit_section);
Note:
See TracChangeset
for help on using the changeset viewer.