|
|
page ,132 ;------------------------------Module-Header----------------------------; ; Module Name: lock.asm ; ; ; ; Contains the ASM versions of locking routines. ; ; ; ; Copyright (c) 1992-1999 Microsoft Corporation ; ;-----------------------------------------------------------------------;
.386 .model small
assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT assume fs:nothing,gs:nothing
.xlist include callconv.inc include ks386.inc include gdii386.inc .list
if GDIPLUS
; See hmgrapi.cxx
else
.data
if DBG HL_AlreadyLocked db 'HmgLock Error: GDI handle already locked by another thread',10,0 HL_OverFlowShareRef db 'Hmg Error: GDI handle share reference count over flowed',10,0 endif
_DATA SEGMENT DWORD PUBLIC 'DATA'
public _GDIpLockPrefixTable _GDIpLockPrefixTable label dword dd offset FLAT:Lock1 dd offset FLAT:Lock4 dd offset FLAT:Lock5 dd offset FLAT:Lock6 dd offset FLAT:Lock7 dd offset FLAT:Lock8 dd 0 _DATA ENDS
OBJECTOWNER_LOCK equ 1h ; First bit of the objectowner OBJECTOWNER_PID equ 0fffffffeh ; The PID bits
.code
extrn _gpentHmgr:dword ; Address of ENTRY array. extrn _gcMaxHmgr:dword extrn _gpLockShortDelay:dword ; Pointer to global constant 10 ms delay
if DBG extrn _DbgPrint:proc EXTRNP _HmgPrintBadHandle,2 endif
EXTRNP _KeDelayExecutionThread,3 EXTRNP HalRequestSoftwareInterrupt,1,IMPORT,FASTCALL EXTRNP _PsGetCurrentProcessId,0
;------------------------------Public-Routine------------------------------; ; HmgInterlockedCompareAndSwap(pul,ulong0,ulong1) ; ; Compare *pul with ulong1, if equal then replace with ulong2 interlocked ; ; Returns: ; EAX = 1 if memory written, 0 if not ; ;--------------------------------------------------------------------------; ; public @HmgInterlockedCompareAndSwap@12 @HmgInterlockedCompareAndSwap@12 proc near
mov eax,edx mov edx,[esp]+4 .486 Lock1: lock cmpxchg [ecx],edx .386 jnz Return_Zero
mov eax,1 ret 4
Return_Zero: xor eax,eax ret 4
@HmgInterlockedCompareAndSwap@12 endp
;------------------------------Public-Routine------------------------------; ; HmgLock (hobj,objt) ; ; Lock a user object. ; ; Input: ; EAX -- scratch ; ECX -- hobj ; EDX -- objt ; ; Returns: ; EAX = pointer to locked object ; ; Error Return: ; EAX = 0, No error logged. ; ; History: ; 14-Jun-1995 -by- J. Andrew Goossen [andrewgo] ; Rewrote for Kernel Mode. ; ; 20-Dec-1993 -by- Patrick Haluptzok [patrickh] ; Move lock counts into object. ; ; 23-Sep-1993 -by- Michael Abrash [mikeab] ; Tuned ASM code. ; ; -Sep-1992 -by- David Cutler [DaveC] ; Write HmgAltLock, HmgAltCheckLock, and HmgObjtype in ASM. ; ; Thu 13-Aug-1992 13:21:47 -by- Charles Whitmer [chuckwh] ; Wrote it in ASM. The common case falls straight through. ; ; Wed 12-Aug-1992 17:38:27 -by- Charles Whitmer [chuckwh] ; Restructured the C code to minimize jumps. ; ; 29-Jun-1991 -by- Patrick Haluptzok patrickh ; Wrote it. ;--------------------------------------------------------------------------;
public @HmgLock@8 @HmgLock@8 proc near push ebx ;Preserve register in call if DBG push ecx ;Stash hobj for debugging push edx ;Stash objt for debugging endif push ecx ;Stash hobj for later
; KeEnterCriticalRegion ; KeGetCurrentThread()->KernelApcDisable -= 1;
mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread() dec WORD PTR [ebx].ThKernelApcDisable
and ecx,INDEX_MASK cmp ecx,_gcMaxHmgr jae HmgLock_bad_handle_before_lock
shl ecx,4 .errnz size ENTRY - 16 add ecx,_gpentHmgr ;ecx -> Entry
HmgLock_resume::
; Perf: It would be nice if we could avoid these word size overrides, ; but unfortunately objectowner_Pid is currently a non-dword ; aligned offset.
mov ebx,[ecx].entry_ObjectOwner stdCall _PsGetCurrentProcessId,<> and eax,OBJECTOWNER_PID and ebx,OBJECTOWNER_PID cmp eax,ebx jne HmgLock_check_for_public_owner
HmgLock_after_check_for_public_owner:: mov eax,[ecx].entry_ObjectOwner mov ebx,[ecx].entry_ObjectOwner and eax,NOT OBJECTOWNER_LOCK or ebx,OBJECTOWNER_LOCK
.486 Lock4: lock cmpxchg [ecx].entry_ObjectOwner,ebx .386 mov ebx,eax ;Remember unlock value jnz HmgLock_delay
; The handle is now locked
cmp dl,[ecx].entry_Objt pop eax jnz HmgLock_bad_handle_after_lock
; Perf: If FullUnique were kept on an odd word-boundary, we could ; avoid the shift word compare and instead do a 32 bit 'xor' ; and 'and':
shr eax,TYPE_SHIFT cmp ax,[ecx].entry_FullUnique jnz HmgLock_bad_handle_after_lock
mov eax,[ecx].entry_einfo mov edx,fs:[PcPrcbData].PbCurrentThread ;edx ->KeGetCurrentThread() cmp word ptr [eax].object_cExclusiveLock,0 ;Note, testing here... ;cExclusiveLock is a USHORT
jnz HmgLock_check_if_same_thread ;...and jumping here mov byte ptr [eax].object_cExclusiveLock,1 ;We can do a byte move ; because we know it was ; a zero word before HmgLock_after_same_thread:: mov [eax].object_Tid,edx mov [ecx].entry_ObjectOwner,ebx ;Unlock it
; eax is set to the proper return value
HmgLock_incAPC::
; KiLeaveCriticalRegion (eax must be preseerved) ; ; #define KiLeaveCriticalRegion() { \ ; PKTHREAD Thread; \ ; Thread = KeGetCurrentThread(); \ ; if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \ ; (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \ ; &Thread->ApcState.ApcListHead[KernelMode])) { \ ; Thread->ApcState.KernelApcPending = TRUE; \ ; KiRequestSoftwareInterrupt(APC_LEVEL); \ ; } \ ; } ;
mov ebx,fs:[PcPrcbData].PbCurrentThread ;eax -> KeGetCurrentThread() inc WORD PTR [ebx].ThKernelApcDisable jz HmgLock_LeaveCriticalRegion
HmgLock_Done::
if DBG pop ebx ;Remove debug copy of objt pop ebx ;Remove debug copy of hobj endif pop ebx ret
; Roads less travelled...
HmgLock_check_for_public_owner: test ebx,ebx .errnz OBJECT_OWNER_PUBLIC jz HmgLock_after_check_for_public_owner
HmgLock_bad_handle_before_lock:: pop ecx jmp HmgLock_bad_handle
HmgLock_bad_handle_after_lock:: mov [ecx].entry_ObjectOwner,ebx ;Unlock it
HmgLock_bad_handle: if DBG ; Retrieve the debug copies of 'hobj' and 'objt' from where they ; were pushed on the stack:
mov eax,[esp] ;objt mov ecx,[esp+4] ;hobj
; Call a debug routine that prints a warning, complete with ; the name of the owning process, handle value, and expected type.
stdCall _HmgPrintBadHandle,<ecx,eax> endif xor eax,eax jmp HmgLock_incAPC
HmgLock_check_if_same_thread:: inc dword ptr [eax].object_cExclusiveLock ; cExclusiveLock is USHORT cmp edx,[eax].object_Tid ; but dword operation is faster on P5 je HmgLock_after_same_thread ; than a word operation
; Error case if already locked:
dec dword ptr [eax].object_cExclusiveLock ; same remark as for inc above mov [ecx].entry_ObjectOwner,ebx ;Unlock it if DBG push offset HL_AlreadyLocked call _DbgPrint add esp,4 endif jmp HmgLock_bad_handle
HmgLock_delay:: push ecx push edx mov eax,_gpLockShortDelay stdCall _KeDelayExecutionThread,<KernelMode,0,eax> pop edx pop ecx mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread() jmp HmgLock_resume
HmgLock_LeaveCriticalRegion:: lea ecx,[ebx].ThApcState+AsApcListHead mov edx,[ecx].LsFlink cmp ecx,edx jne HmgLock_CallInterrupt
if DBG pop ebx ;Remove debug copy of objt pop ebx ;Remove debug copy of hobj endif pop ebx ret
HmgLock_CallInterrupt::
lea ecx,[ebx].ThApcState mov BYTE PTR [ecx].AsKernelApcPending,1 push eax mov ecx,APC_LEVEL fstCall HalRequestSoftwareInterrupt pop eax jmp HmgLock_Done
@HmgLock@8 endp
;------------------------------Public-Routine------------------------------; ; HmgShareCheckLock (hobj,objt) ; ; Acquire a share lock on an object, PID owner must match current PID ; or be a public. ; ; Input: ; EAX -- scratch ; ECX -- hobj ; EDX -- objt ; ; Returns: ; EAX = pointer to referenced object ; ; Error Return: ; EAX = 0, No error logged. ; ;--------------------------------------------------------------------------;
public @HmgShareCheckLock@8 @HmgShareCheckLock@8 proc near push ebx ;Preserve register in call if DBG push ecx ;Stash hobj for debugging push edx ;Stash objt for debugging endif push ecx ;Stash hobj for later
; KeEnterCriticalRegion ; KeGetCurrentThread()->KernelApcDisable -= 1;
mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread() dec WORD PTR [ebx].ThKernelApcDisable
and ecx,INDEX_MASK cmp ecx,_gcMaxHmgr jae HmgShareCheckLock_bad_handle_before_lock
shl ecx,4 .errnz size ENTRY - 16 add ecx,_gpentHmgr ;ecx -> Entry
HmgShareCheckLock_resume::
; Perf: It would be nice if we could avoid these word size overrides, ; but unfortunately objectowner_Pid is currently a non-dword ; aligned offset.
mov ebx,[ecx].entry_ObjectOwner stdCall _PsGetCurrentProcessId,<> and eax,OBJECTOWNER_PID and ebx,OBJECTOWNER_PID cmp eax,ebx jne HmgShareCheckLock_check_for_public_owner
HmgShareCheckLock_after_check_for_public_owner:: mov eax,[ecx].entry_ObjectOwner mov ebx,[ecx].entry_ObjectOwner and eax,NOT OBJECTOWNER_LOCK or ebx,OBJECTOWNER_LOCK
.486 Lock5: lock cmpxchg [ecx].entry_ObjectOwner,ebx .386 mov ebx,eax ;Remember unlock value jnz HmgShareCheckLock_delay
; The handle is now locked
cmp dl,[ecx].entry_Objt pop eax jnz HmgShareCheckLock_bad_handle_after_lock
; Perf: If FullUnique were kept on an odd word-boundary, we could ; avoid the shift word compare and instead do a 32 bit 'xor' ; and 'and':
shr eax,TYPE_SHIFT cmp ax,[ecx].entry_FullUnique jnz HmgShareCheckLock_bad_handle_after_lock mov eax,[ecx].entry_einfo ;Get pointer to object if DBG cmp [eax].object_ulShareCount, 0ffffffffH ;Check for overflow jne HmgShareCheckLock_go push offset HL_OverFlowShareRef call _DbgPrint add esp,4 int 3 HmgShareCheckLock_go: endif inc DWORD PTR [eax].object_ulShareCount mov [ecx].entry_ObjectOwner,ebx ;Unlock it
HmgShareCheckLock_IncAPC::
; KiLeaveCriticalRegion (eax must be preseerved) ; ; #define KiLeaveCriticalRegion() { \ ; PKTHREAD Thread; \ ; Thread = KeGetCurrentThread(); \ ; if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \ ; (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \ ; &Thread->ApcState.ApcListHead[KernelMode])) { \ ; Thread->ApcState.KernelApcPending = TRUE; \ ; KiRequestSoftwareInterrupt(APC_LEVEL); \ ; } \ ; } ;
mov ebx,fs:[PcPrcbData].PbCurrentThread ;eax -> KeGetCurrentThread() inc WORD PTR [ebx].ThKernelApcDisable jz HmgShareCheckLock_LeaveCriticalRegion
; eax is set to the proper return value
HmgShareCheckLock_Done:: if DBG pop ebx ;Remove debug copy of objt pop ebx ;Remove debug copy of hobj endif pop ebx ret
; Roads less travelled...
HmgShareCheckLock_check_for_public_owner: test ebx,ebx .errnz OBJECT_OWNER_PUBLIC jz HmgShareCheckLock_after_check_for_public_owner HmgShareCheckLock_bad_handle_before_lock:: pop ecx jmp HmgShareCheckLock_bad_handle
HmgShareCheckLock_bad_handle_after_lock:: mov [ecx].entry_ObjectOwner,ebx ;Unlock it
HmgShareCheckLock_bad_handle:: if DBG ; Retrieve the debug copies of 'hobj' and 'objt' from where they ; were pushed on the stack:
mov eax,[esp] ;objt mov ecx,[esp+4] ;hobj
; Call a debug routine that prints a warning, complete with ; the name of the owning process, handle value, and expected type.
stdCall _HmgPrintBadHandle,<ecx,eax> endif xor eax,eax jmp HmgShareCheckLock_IncAPC
HmgShareCheckLock_delay:: push ecx push edx mov eax,_gpLockShortDelay stdCall _KeDelayExecutionThread,<KernelMode,0,eax> pop edx pop ecx mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread() jmp HmgShareCheckLock_resume
HmgShareCheckLock_LeaveCriticalRegion:: lea ecx,[ebx].ThApcState+AsApcListHead mov edx,[ecx].LsFlink cmp ecx,edx jne HmgShareCheckLock_CallInterrupt
if DBG pop ebx ;Remove debug copy of objt pop ebx ;Remove debug copy of hobj endif pop ebx ret
HmgShareCheckLock_CallInterrupt::
lea ecx,[ebx].ThApcState mov BYTE PTR [ecx].AsKernelApcPending,1 push eax mov ecx,APC_LEVEL fstCall HalRequestSoftwareInterrupt pop eax jmp HmgShareCheckLock_Done
@HmgShareCheckLock@8 endp
;------------------------------Public-Routine------------------------------; ; HmgShareLock (obj,objt) ; ; ; Acquire a share lock on an object, don't check PID owner ; ; Input: ; EAX -- scratch ; ECX -- hobj ; EDX -- objt ; ; Returns: ; EAX = pointer to referenced object ; ; Error Return: ; EAX = 0, No error logged. ; ;--------------------------------------------------------------------------;
public @HmgShareLock@8 @HmgShareLock@8 proc near push ebx ;Preserve register in call if DBG push ecx ;Stash hobj for debugging push edx ;Stash objt for debugging endif push ecx ;Stash hobj for later
; KeEnterCriticalRegion ; KeGetCurrentThread()->KernelApcDisable -= 1;
mov ebx,fs:[PcPrcbData].PbCurrentThread ;eax -> KeGetCurrentThread() dec WORD PTR [ebx].ThKernelApcDisable
and ecx,INDEX_MASK cmp ecx,_gcMaxHmgr jae HmgShareLock_bad_handle_before_lock
shl ecx,4 .errnz size ENTRY - 16 add ecx,_gpentHmgr ;ecx -> Entry
HmgShareLock_resume:: mov eax,[ecx].entry_ObjectOwner mov ebx,[ecx].entry_ObjectOwner and eax,NOT OBJECTOWNER_LOCK or ebx,OBJECTOWNER_LOCK
.486 Lock6: lock cmpxchg [ecx].entry_ObjectOwner,ebx .386 mov ebx,eax ;Remember unlock value jnz HmgShareLock_delay
; The handle is now locked
cmp dl,[ecx].entry_Objt pop eax jnz HmgShareLock_bad_handle_after_lock
; Perf: If FullUnique were kept on an odd word-boundary, we could ; avoid the shift word compare and instead do a 32 bit 'xor' ; and 'and':
shr eax,TYPE_SHIFT cmp ax,[ecx].entry_FullUnique jnz HmgShareLock_bad_handle_after_lock mov eax,[ecx].entry_einfo ;Get pointer to object if DBG cmp [eax].object_ulShareCount, 0ffffffffH ;Check for overflow jne HmgShareLock_go push offset HL_OverFlowShareRef call _DbgPrint add esp,4 int 3 HmgShareLock_go: endif inc DWORD PTR [eax].object_ulShareCount mov [ecx].entry_ObjectOwner,ebx ;Unlock it
HmgShareLock_incAPC::
; KiLeaveCriticalRegion (eax must be preseerved) ; ; #define KiLeaveCriticalRegion() { \ ; PKTHREAD Thread; \ ; Thread = KeGetCurrentThread(); \ ; if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \ ; (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \ ; &Thread->ApcState.ApcListHead[KernelMode])) { \ ; Thread->ApcState.KernelApcPending = TRUE; \ ; KiRequestSoftwareInterrupt(APC_LEVEL); \ ; } \ ; } ;
mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread() inc WORD PTR [ebx].ThKernelApcDisable jz HmgShareLock_LeaveCriticalRegion
HmgShareLock_Done::
; eax is set to the proper return value
if DBG pop ebx ;Remove debug copy of objt pop ebx ;Remove debug copy of hobj endif pop ebx ret
; Roads less travelled...
HmgShareLock_bad_handle_before_lock:: pop ecx jmp HmgShareLock_bad_handle
HmgShareLock_bad_handle_after_lock:: mov [ecx].entry_ObjectOwner,ebx ;Unlock it
HmgShareLock_bad_handle:: if DBG ; Retrieve the debug copies of 'hobj' and 'objt' from where they ; were pushed on the stack:
mov eax,[esp] ;objt mov ecx,[esp+4] ;hobj
; Call a debug routine that prints a warning, complete with ; the name of the owning process, handle value, and expected type.
stdCall _HmgPrintBadHandle,<ecx,eax> endif xor eax,eax jmp HmgShareLock_incAPC
HmgShareLock_delay:: push ecx push edx mov eax,_gpLockShortDelay stdCall _KeDelayExecutionThread,<KernelMode,0,eax> pop edx pop ecx jmp HmgShareLock_resume
HmgShareLock_LeaveCriticalRegion:: lea ecx,[ebx].ThApcState+AsApcListHead mov edx,[ecx].LsFlink cmp ecx,edx jne HmgShareLock_CallInterrupt
if DBG pop ebx ;Remove debug copy of objt pop ebx ;Remove debug copy of hobj endif pop ebx ret
HmgShareLock_CallInterrupt::
lea ecx,[ebx].ThApcState mov BYTE PTR [ecx].AsKernelApcPending,1 push eax mov ecx,APC_LEVEL fstCall HalRequestSoftwareInterrupt pop eax jmp HmgShareLock_Done
@HmgShareLock@8 endp
;------------------------------Public-Routine------------------------------; ; HmgIncrementShareReferenceCount (pobj) ; ; ; Increment shared reference count, no checking ; ; Input: ; EAX -- scratch ; ECX -- pobj ; ; Returns: ; EAX = pointer to referenced object ; ; Error Return: ; EAX = 0, No error logged. ; ;--------------------------------------------------------------------------;
public @HmgIncrementShareReferenceCount@4 @HmgIncrementShareReferenceCount@4 proc near push ebx ;Preserve register in call push ecx ;Stash pobj for later
; KeEnterCriticalRegion ; KeGetCurrentThread()->KernelApcDisable -= 1;
mov ebx,fs:[PcPrcbData].PbCurrentThread ;eax -> KeGetCurrentThread() dec WORD PTR [ebx].ThKernelApcDisable
mov ecx, [ecx] and ecx,INDEX_MASK
shl ecx,4 .errnz size ENTRY - 16 add ecx,_gpentHmgr ;ecx -> Entry
HmgIncrementShareReferenceCount_resume:: mov eax,[ecx].entry_ObjectOwner mov ebx,[ecx].entry_ObjectOwner and eax,NOT OBJECTOWNER_LOCK or ebx,OBJECTOWNER_LOCK
.486 Lock7: lock cmpxchg [ecx].entry_ObjectOwner,ebx .386 mov ebx,eax ;Remember unlock value jnz HmgIncrementShareReferenceCount_delay
; The handle is now locked mov eax,[ecx].entry_einfo ;Get pointer to object
inc DWORD PTR [eax].object_ulShareCount mov [ecx].entry_ObjectOwner,ebx ;Unlock it
HmgIncrementShareReferenceCount_incAPC::
; KiLeaveCriticalRegion (eax must be preseerved) ; ; #define KiLeaveCriticalRegion() { \ ; PKTHREAD Thread; \ ; Thread = KeGetCurrentThread(); \ ; if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \ ; (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \ ; &Thread->ApcState.ApcListHead[KernelMode])) { \ ; Thread->ApcState.KernelApcPending = TRUE; \ ; KiRequestSoftwareInterrupt(APC_LEVEL); \ ; } \ ; } ;
mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread() inc WORD PTR [ebx].ThKernelApcDisable jz HmgIncrementShareReferenceCount_LeaveCriticalRegion
HmgIncrementShareReferenceCount_Done::
; eax is set to the proper return value
pop ecx pop ebx ret
; Roads less travelled...
HmgIncrementShareReferenceCount_delay:: push ecx mov eax,_gpLockShortDelay stdCall _KeDelayExecutionThread,<KernelMode,0,eax> pop ecx jmp HmgIncrementShareReferenceCount_resume
HmgIncrementShareReferenceCount_LeaveCriticalRegion:: lea ecx,[ebx].ThApcState+AsApcListHead mov edx,[ecx].LsFlink cmp ecx,edx jne HmgIncrementShareReferenceCount_CallInterrupt
pop ecx pop ebx ret
HmgIncrementShareReferenceCount_CallInterrupt::
lea ecx,[ebx].ThApcState mov BYTE PTR [ecx].AsKernelApcPending,1 push eax mov ecx,APC_LEVEL fstCall HalRequestSoftwareInterrupt pop eax jmp HmgIncrementShareReferenceCount_Done
@HmgIncrementShareReferenceCount@4 endp
;------------------------------Public-Routine------------------------------; ; HmgDecrementShareReferenceCount (pobj) ; ; ; Decrement shared reference count, no checking ; ; Input: ; EAX -- scratch ; ECX -- pobj ; ; Returns: ; ; Error Return: ; EAX = 0, No error logged. ; ;--------------------------------------------------------------------------;
public @HmgDecrementShareReferenceCount@4 @HmgDecrementShareReferenceCount@4 proc near push ebx ;Preserve register in call push ecx ;Stash pobj for later
; KeEnterCriticalRegion ; KeGetCurrentThread()->KernelApcDisable -= 1;
mov ebx,fs:[PcPrcbData].PbCurrentThread ;eax -> KeGetCurrentThread() dec WORD PTR [ebx].ThKernelApcDisable
mov ecx, [ecx] and ecx,INDEX_MASK
shl ecx,4 .errnz size ENTRY - 16 add ecx,_gpentHmgr ;ecx -> Entry
HmgDecrementShareReferenceCount_resume:: mov eax,[ecx].entry_ObjectOwner mov ebx,[ecx].entry_ObjectOwner and eax,NOT OBJECTOWNER_LOCK or ebx,OBJECTOWNER_LOCK
.486 Lock8: lock cmpxchg [ecx].entry_ObjectOwner,ebx .386 mov ebx,eax ;Remember unlock value jnz HmgDecrementShareReferenceCount_delay
; The handle is now locked mov edx,[ecx].entry_einfo ;Get pointer to object
mov eax, [edx].object_ulShareCount dec DWORD PTR [edx].object_ulShareCount mov [ecx].entry_ObjectOwner,ebx ;Unlock it
HmgDecrementShareReferenceCount_incAPC::
; KiLeaveCriticalRegion (eax must be preseerved) ; ; #define KiLeaveCriticalRegion() { \ ; PKTHREAD Thread; \ ; Thread = KeGetCurrentThread(); \ ; if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \ ; (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \ ; &Thread->ApcState.ApcListHead[KernelMode])) { \ ; Thread->ApcState.KernelApcPending = TRUE; \ ; KiRequestSoftwareInterrupt(APC_LEVEL); \ ; } \ ; } ;
mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread() inc WORD PTR [ebx].ThKernelApcDisable jz HmgDecrementShareReferenceCount_LeaveCriticalRegion
HmgDecrementShareReferenceCount_Done::
; eax is set to the proper return value pop ecx pop ebx ret
; Roads less travelled...
HmgDecrementShareReferenceCount_delay:: push ecx mov eax,_gpLockShortDelay stdCall _KeDelayExecutionThread,<KernelMode,0,eax> pop ecx jmp HmgDecrementShareReferenceCount_resume
HmgDecrementShareReferenceCount_LeaveCriticalRegion:: lea ecx,[ebx].ThApcState+AsApcListHead mov edx,[ecx].LsFlink cmp ecx,edx jne HmgDecrementShareReferenceCount_CallInterrupt
pop ecx pop ebx ret
HmgDecrementShareReferenceCount_CallInterrupt::
lea ecx,[ebx].ThApcState mov BYTE PTR [ecx].AsKernelApcPending,1 push eax mov ecx,APC_LEVEL fstCall HalRequestSoftwareInterrupt pop eax jmp HmgDecrementShareReferenceCount_Done
@HmgDecrementShareReferenceCount@4 endp
_TEXT ends
endif
end
|