Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

923 lines
30 KiB

  1. page ,132
  2. ;------------------------------Module-Header----------------------------;
  3. ; Module Name: lock.asm ;
  4. ; ;
  5. ; Contains the ASM versions of locking routines. ;
  6. ; ;
  7. ; Copyright (c) 1992-1999 Microsoft Corporation ;
  8. ;-----------------------------------------------------------------------;
  9. .386
  10. .model small
  11. assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
  12. assume fs:nothing,gs:nothing
  13. .xlist
  14. include callconv.inc
  15. include ks386.inc
  16. include gdii386.inc
  17. .list
  18. if GDIPLUS
  19. ; See hmgrapi.cxx
  20. else
  21. .data
  22. if DBG
  23. HL_AlreadyLocked db 'HmgLock Error: GDI handle already locked by another thread',10,0
  24. HL_OverFlowShareRef db 'Hmg Error: GDI handle share reference count over flowed',10,0
  25. endif
  26. _DATA SEGMENT DWORD PUBLIC 'DATA'
  27. public _GDIpLockPrefixTable
  28. _GDIpLockPrefixTable label dword
  29. dd offset FLAT:Lock1
  30. dd offset FLAT:Lock4
  31. dd offset FLAT:Lock5
  32. dd offset FLAT:Lock6
  33. dd offset FLAT:Lock7
  34. dd offset FLAT:Lock8
  35. dd 0
  36. _DATA ENDS
  37. OBJECTOWNER_LOCK equ 1h ; First bit of the objectowner
  38. OBJECTOWNER_PID equ 0fffffffeh ; The PID bits
  39. .code
  40. extrn _gpentHmgr:dword ; Address of ENTRY array.
  41. extrn _gcMaxHmgr:dword
  42. extrn _gpLockShortDelay:dword ; Pointer to global constant 10 ms delay
  43. if DBG
  44. extrn _DbgPrint:proc
  45. EXTRNP _HmgPrintBadHandle,2
  46. endif
  47. EXTRNP _KeDelayExecutionThread,3
  48. EXTRNP HalRequestSoftwareInterrupt,1,IMPORT,FASTCALL
  49. EXTRNP _PsGetCurrentProcessId,0
  50. ;------------------------------Public-Routine------------------------------;
  51. ; HmgInterlockedCompareAndSwap(pul,ulong0,ulong1)
  52. ;
  53. ; Compare *pul with ulong1, if equal then replace with ulong2 interlocked
  54. ;
  55. ; Returns:
  56. ; EAX = 1 if memory written, 0 if not
  57. ;
  58. ;--------------------------------------------------------------------------;
  59. ;
  60. public @HmgInterlockedCompareAndSwap@12
  61. @HmgInterlockedCompareAndSwap@12 proc near
  62. mov eax,edx
  63. mov edx,[esp]+4
  64. .486
  65. Lock1:
  66. lock cmpxchg [ecx],edx
  67. .386
  68. jnz Return_Zero
  69. mov eax,1
  70. ret 4
  71. Return_Zero:
  72. xor eax,eax
  73. ret 4
  74. @HmgInterlockedCompareAndSwap@12 endp
  75. ;------------------------------Public-Routine------------------------------;
  76. ; HmgLock (hobj,objt)
  77. ;
  78. ; Lock a user object.
  79. ;
  80. ; Input:
  81. ; EAX -- scratch
  82. ; ECX -- hobj
  83. ; EDX -- objt
  84. ;
  85. ; Returns:
  86. ; EAX = pointer to locked object
  87. ;
  88. ; Error Return:
  89. ; EAX = 0, No error logged.
  90. ;
  91. ; History:
  92. ; 14-Jun-1995 -by- J. Andrew Goossen [andrewgo]
  93. ; Rewrote for Kernel Mode.
  94. ;
  95. ; 20-Dec-1993 -by- Patrick Haluptzok [patrickh]
  96. ; Move lock counts into object.
  97. ;
  98. ; 23-Sep-1993 -by- Michael Abrash [mikeab]
  99. ; Tuned ASM code.
  100. ;
  101. ; -Sep-1992 -by- David Cutler [DaveC]
  102. ; Write HmgAltLock, HmgAltCheckLock, and HmgObjtype in ASM.
  103. ;
  104. ; Thu 13-Aug-1992 13:21:47 -by- Charles Whitmer [chuckwh]
  105. ; Wrote it in ASM. The common case falls straight through.
  106. ;
  107. ; Wed 12-Aug-1992 17:38:27 -by- Charles Whitmer [chuckwh]
  108. ; Restructured the C code to minimize jumps.
  109. ;
  110. ; 29-Jun-1991 -by- Patrick Haluptzok patrickh
  111. ; Wrote it.
  112. ;--------------------------------------------------------------------------;
  113. public @HmgLock@8
  114. @HmgLock@8 proc near
  115. push ebx ;Preserve register in call
  116. if DBG
  117. push ecx ;Stash hobj for debugging
  118. push edx ;Stash objt for debugging
  119. endif
  120. push ecx ;Stash hobj for later
  121. ; KeEnterCriticalRegion
  122. ; KeGetCurrentThread()->KernelApcDisable -= 1;
  123. mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread()
  124. dec WORD PTR [ebx].ThKernelApcDisable
  125. and ecx,INDEX_MASK
  126. cmp ecx,_gcMaxHmgr
  127. jae HmgLock_bad_handle_before_lock
  128. shl ecx,4
  129. .errnz size ENTRY - 16
  130. add ecx,_gpentHmgr ;ecx -> Entry
  131. HmgLock_resume::
  132. ; Perf: It would be nice if we could avoid these word size overrides,
  133. ; but unfortunately objectowner_Pid is currently a non-dword
  134. ; aligned offset.
  135. mov ebx,[ecx].entry_ObjectOwner
  136. stdCall _PsGetCurrentProcessId,<>
  137. and eax,OBJECTOWNER_PID
  138. and ebx,OBJECTOWNER_PID
  139. cmp eax,ebx
  140. jne HmgLock_check_for_public_owner
  141. HmgLock_after_check_for_public_owner::
  142. mov eax,[ecx].entry_ObjectOwner
  143. mov ebx,[ecx].entry_ObjectOwner
  144. and eax,NOT OBJECTOWNER_LOCK
  145. or ebx,OBJECTOWNER_LOCK
  146. .486
  147. Lock4:
  148. lock cmpxchg [ecx].entry_ObjectOwner,ebx
  149. .386
  150. mov ebx,eax ;Remember unlock value
  151. jnz HmgLock_delay
  152. ; The handle is now locked
  153. cmp dl,[ecx].entry_Objt
  154. pop eax
  155. jnz HmgLock_bad_handle_after_lock
  156. ; Perf: If FullUnique were kept on an odd word-boundary, we could
  157. ; avoid the shift word compare and instead do a 32 bit 'xor'
  158. ; and 'and':
  159. shr eax,TYPE_SHIFT
  160. cmp ax,[ecx].entry_FullUnique
  161. jnz HmgLock_bad_handle_after_lock
  162. mov eax,[ecx].entry_einfo
  163. mov edx,fs:[PcPrcbData].PbCurrentThread ;edx ->KeGetCurrentThread()
  164. cmp word ptr [eax].object_cExclusiveLock,0 ;Note, testing here...
  165. ;cExclusiveLock is a USHORT
  166. jnz HmgLock_check_if_same_thread ;...and jumping here
  167. mov byte ptr [eax].object_cExclusiveLock,1
  168. ;We can do a byte move
  169. ; because we know it was
  170. ; a zero word before
  171. HmgLock_after_same_thread::
  172. mov [eax].object_Tid,edx
  173. mov [ecx].entry_ObjectOwner,ebx ;Unlock it
  174. ; eax is set to the proper return value
  175. HmgLock_incAPC::
  176. ; KiLeaveCriticalRegion (eax must be preseerved)
  177. ;
  178. ; #define KiLeaveCriticalRegion() { \
  179. ; PKTHREAD Thread; \
  180. ; Thread = KeGetCurrentThread(); \
  181. ; if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \
  182. ; (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \
  183. ; &Thread->ApcState.ApcListHead[KernelMode])) { \
  184. ; Thread->ApcState.KernelApcPending = TRUE; \
  185. ; KiRequestSoftwareInterrupt(APC_LEVEL); \
  186. ; } \
  187. ; }
  188. ;
  189. mov ebx,fs:[PcPrcbData].PbCurrentThread ;eax -> KeGetCurrentThread()
  190. inc WORD PTR [ebx].ThKernelApcDisable
  191. jz HmgLock_LeaveCriticalRegion
  192. HmgLock_Done::
  193. if DBG
  194. pop ebx ;Remove debug copy of objt
  195. pop ebx ;Remove debug copy of hobj
  196. endif
  197. pop ebx
  198. ret
  199. ; Roads less travelled...
  200. HmgLock_check_for_public_owner:
  201. test ebx,ebx
  202. .errnz OBJECT_OWNER_PUBLIC
  203. jz HmgLock_after_check_for_public_owner
  204. HmgLock_bad_handle_before_lock::
  205. pop ecx
  206. jmp HmgLock_bad_handle
  207. HmgLock_bad_handle_after_lock::
  208. mov [ecx].entry_ObjectOwner,ebx ;Unlock it
  209. HmgLock_bad_handle:
  210. if DBG
  211. ; Retrieve the debug copies of 'hobj' and 'objt' from where they
  212. ; were pushed on the stack:
  213. mov eax,[esp] ;objt
  214. mov ecx,[esp+4] ;hobj
  215. ; Call a debug routine that prints a warning, complete with
  216. ; the name of the owning process, handle value, and expected type.
  217. stdCall _HmgPrintBadHandle,<ecx,eax>
  218. endif
  219. xor eax,eax
  220. jmp HmgLock_incAPC
  221. HmgLock_check_if_same_thread::
  222. inc dword ptr [eax].object_cExclusiveLock ; cExclusiveLock is USHORT
  223. cmp edx,[eax].object_Tid ; but dword operation is faster on P5
  224. je HmgLock_after_same_thread ; than a word operation
  225. ; Error case if already locked:
  226. dec dword ptr [eax].object_cExclusiveLock ; same remark as for inc above
  227. mov [ecx].entry_ObjectOwner,ebx ;Unlock it
  228. if DBG
  229. push offset HL_AlreadyLocked
  230. call _DbgPrint
  231. add esp,4
  232. endif
  233. jmp HmgLock_bad_handle
  234. HmgLock_delay::
  235. push ecx
  236. push edx
  237. mov eax,_gpLockShortDelay
  238. stdCall _KeDelayExecutionThread,<KernelMode,0,eax>
  239. pop edx
  240. pop ecx
  241. mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread()
  242. jmp HmgLock_resume
  243. HmgLock_LeaveCriticalRegion::
  244. lea ecx,[ebx].ThApcState+AsApcListHead
  245. mov edx,[ecx].LsFlink
  246. cmp ecx,edx
  247. jne HmgLock_CallInterrupt
  248. if DBG
  249. pop ebx ;Remove debug copy of objt
  250. pop ebx ;Remove debug copy of hobj
  251. endif
  252. pop ebx
  253. ret
  254. HmgLock_CallInterrupt::
  255. lea ecx,[ebx].ThApcState
  256. mov BYTE PTR [ecx].AsKernelApcPending,1
  257. push eax
  258. mov ecx,APC_LEVEL
  259. fstCall HalRequestSoftwareInterrupt
  260. pop eax
  261. jmp HmgLock_Done
  262. @HmgLock@8 endp
  263. ;------------------------------Public-Routine------------------------------;
  264. ; HmgShareCheckLock (hobj,objt)
  265. ;
  266. ; Acquire a share lock on an object, PID owner must match current PID
  267. ; or be a public.
  268. ;
  269. ; Input:
  270. ; EAX -- scratch
  271. ; ECX -- hobj
  272. ; EDX -- objt
  273. ;
  274. ; Returns:
  275. ; EAX = pointer to referenced object
  276. ;
  277. ; Error Return:
  278. ; EAX = 0, No error logged.
  279. ;
  280. ;--------------------------------------------------------------------------;
  281. public @HmgShareCheckLock@8
  282. @HmgShareCheckLock@8 proc near
  283. push ebx ;Preserve register in call
  284. if DBG
  285. push ecx ;Stash hobj for debugging
  286. push edx ;Stash objt for debugging
  287. endif
  288. push ecx ;Stash hobj for later
  289. ; KeEnterCriticalRegion
  290. ; KeGetCurrentThread()->KernelApcDisable -= 1;
  291. mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread()
  292. dec WORD PTR [ebx].ThKernelApcDisable
  293. and ecx,INDEX_MASK
  294. cmp ecx,_gcMaxHmgr
  295. jae HmgShareCheckLock_bad_handle_before_lock
  296. shl ecx,4
  297. .errnz size ENTRY - 16
  298. add ecx,_gpentHmgr ;ecx -> Entry
  299. HmgShareCheckLock_resume::
  300. ; Perf: It would be nice if we could avoid these word size overrides,
  301. ; but unfortunately objectowner_Pid is currently a non-dword
  302. ; aligned offset.
  303. mov ebx,[ecx].entry_ObjectOwner
  304. stdCall _PsGetCurrentProcessId,<>
  305. and eax,OBJECTOWNER_PID
  306. and ebx,OBJECTOWNER_PID
  307. cmp eax,ebx
  308. jne HmgShareCheckLock_check_for_public_owner
  309. HmgShareCheckLock_after_check_for_public_owner::
  310. mov eax,[ecx].entry_ObjectOwner
  311. mov ebx,[ecx].entry_ObjectOwner
  312. and eax,NOT OBJECTOWNER_LOCK
  313. or ebx,OBJECTOWNER_LOCK
  314. .486
  315. Lock5:
  316. lock cmpxchg [ecx].entry_ObjectOwner,ebx
  317. .386
  318. mov ebx,eax ;Remember unlock value
  319. jnz HmgShareCheckLock_delay
  320. ; The handle is now locked
  321. cmp dl,[ecx].entry_Objt
  322. pop eax
  323. jnz HmgShareCheckLock_bad_handle_after_lock
  324. ; Perf: If FullUnique were kept on an odd word-boundary, we could
  325. ; avoid the shift word compare and instead do a 32 bit 'xor'
  326. ; and 'and':
  327. shr eax,TYPE_SHIFT
  328. cmp ax,[ecx].entry_FullUnique
  329. jnz HmgShareCheckLock_bad_handle_after_lock
  330. mov eax,[ecx].entry_einfo ;Get pointer to object
  331. if DBG
  332. cmp [eax].object_ulShareCount, 0ffffffffH ;Check for overflow
  333. jne HmgShareCheckLock_go
  334. push offset HL_OverFlowShareRef
  335. call _DbgPrint
  336. add esp,4
  337. int 3
  338. HmgShareCheckLock_go:
  339. endif
  340. inc DWORD PTR [eax].object_ulShareCount
  341. mov [ecx].entry_ObjectOwner,ebx ;Unlock it
  342. HmgShareCheckLock_IncAPC::
  343. ; KiLeaveCriticalRegion (eax must be preseerved)
  344. ;
  345. ; #define KiLeaveCriticalRegion() { \
  346. ; PKTHREAD Thread; \
  347. ; Thread = KeGetCurrentThread(); \
  348. ; if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \
  349. ; (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \
  350. ; &Thread->ApcState.ApcListHead[KernelMode])) { \
  351. ; Thread->ApcState.KernelApcPending = TRUE; \
  352. ; KiRequestSoftwareInterrupt(APC_LEVEL); \
  353. ; } \
  354. ; }
  355. ;
  356. mov ebx,fs:[PcPrcbData].PbCurrentThread ;eax -> KeGetCurrentThread()
  357. inc WORD PTR [ebx].ThKernelApcDisable
  358. jz HmgShareCheckLock_LeaveCriticalRegion
  359. ; eax is set to the proper return value
  360. HmgShareCheckLock_Done::
  361. if DBG
  362. pop ebx ;Remove debug copy of objt
  363. pop ebx ;Remove debug copy of hobj
  364. endif
  365. pop ebx
  366. ret
  367. ; Roads less travelled...
  368. HmgShareCheckLock_check_for_public_owner:
  369. test ebx,ebx
  370. .errnz OBJECT_OWNER_PUBLIC
  371. jz HmgShareCheckLock_after_check_for_public_owner
  372. HmgShareCheckLock_bad_handle_before_lock::
  373. pop ecx
  374. jmp HmgShareCheckLock_bad_handle
  375. HmgShareCheckLock_bad_handle_after_lock::
  376. mov [ecx].entry_ObjectOwner,ebx ;Unlock it
  377. HmgShareCheckLock_bad_handle::
  378. if DBG
  379. ; Retrieve the debug copies of 'hobj' and 'objt' from where they
  380. ; were pushed on the stack:
  381. mov eax,[esp] ;objt
  382. mov ecx,[esp+4] ;hobj
  383. ; Call a debug routine that prints a warning, complete with
  384. ; the name of the owning process, handle value, and expected type.
  385. stdCall _HmgPrintBadHandle,<ecx,eax>
  386. endif
  387. xor eax,eax
  388. jmp HmgShareCheckLock_IncAPC
  389. HmgShareCheckLock_delay::
  390. push ecx
  391. push edx
  392. mov eax,_gpLockShortDelay
  393. stdCall _KeDelayExecutionThread,<KernelMode,0,eax>
  394. pop edx
  395. pop ecx
  396. mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread()
  397. jmp HmgShareCheckLock_resume
  398. HmgShareCheckLock_LeaveCriticalRegion::
  399. lea ecx,[ebx].ThApcState+AsApcListHead
  400. mov edx,[ecx].LsFlink
  401. cmp ecx,edx
  402. jne HmgShareCheckLock_CallInterrupt
  403. if DBG
  404. pop ebx ;Remove debug copy of objt
  405. pop ebx ;Remove debug copy of hobj
  406. endif
  407. pop ebx
  408. ret
  409. HmgShareCheckLock_CallInterrupt::
  410. lea ecx,[ebx].ThApcState
  411. mov BYTE PTR [ecx].AsKernelApcPending,1
  412. push eax
  413. mov ecx,APC_LEVEL
  414. fstCall HalRequestSoftwareInterrupt
  415. pop eax
  416. jmp HmgShareCheckLock_Done
  417. @HmgShareCheckLock@8 endp
  418. ;------------------------------Public-Routine------------------------------;
  419. ; HmgShareLock (obj,objt)
  420. ;
  421. ;
  422. ; Acquire a share lock on an object, don't check PID owner
  423. ;
  424. ; Input:
  425. ; EAX -- scratch
  426. ; ECX -- hobj
  427. ; EDX -- objt
  428. ;
  429. ; Returns:
  430. ; EAX = pointer to referenced object
  431. ;
  432. ; Error Return:
  433. ; EAX = 0, No error logged.
  434. ;
  435. ;--------------------------------------------------------------------------;
  436. public @HmgShareLock@8
  437. @HmgShareLock@8 proc near
  438. push ebx ;Preserve register in call
  439. if DBG
  440. push ecx ;Stash hobj for debugging
  441. push edx ;Stash objt for debugging
  442. endif
  443. push ecx ;Stash hobj for later
  444. ; KeEnterCriticalRegion
  445. ; KeGetCurrentThread()->KernelApcDisable -= 1;
  446. mov ebx,fs:[PcPrcbData].PbCurrentThread ;eax -> KeGetCurrentThread()
  447. dec WORD PTR [ebx].ThKernelApcDisable
  448. and ecx,INDEX_MASK
  449. cmp ecx,_gcMaxHmgr
  450. jae HmgShareLock_bad_handle_before_lock
  451. shl ecx,4
  452. .errnz size ENTRY - 16
  453. add ecx,_gpentHmgr ;ecx -> Entry
  454. HmgShareLock_resume::
  455. mov eax,[ecx].entry_ObjectOwner
  456. mov ebx,[ecx].entry_ObjectOwner
  457. and eax,NOT OBJECTOWNER_LOCK
  458. or ebx,OBJECTOWNER_LOCK
  459. .486
  460. Lock6:
  461. lock cmpxchg [ecx].entry_ObjectOwner,ebx
  462. .386
  463. mov ebx,eax ;Remember unlock value
  464. jnz HmgShareLock_delay
  465. ; The handle is now locked
  466. cmp dl,[ecx].entry_Objt
  467. pop eax
  468. jnz HmgShareLock_bad_handle_after_lock
  469. ; Perf: If FullUnique were kept on an odd word-boundary, we could
  470. ; avoid the shift word compare and instead do a 32 bit 'xor'
  471. ; and 'and':
  472. shr eax,TYPE_SHIFT
  473. cmp ax,[ecx].entry_FullUnique
  474. jnz HmgShareLock_bad_handle_after_lock
  475. mov eax,[ecx].entry_einfo ;Get pointer to object
  476. if DBG
  477. cmp [eax].object_ulShareCount, 0ffffffffH ;Check for overflow
  478. jne HmgShareLock_go
  479. push offset HL_OverFlowShareRef
  480. call _DbgPrint
  481. add esp,4
  482. int 3
  483. HmgShareLock_go:
  484. endif
  485. inc DWORD PTR [eax].object_ulShareCount
  486. mov [ecx].entry_ObjectOwner,ebx ;Unlock it
  487. HmgShareLock_incAPC::
  488. ; KiLeaveCriticalRegion (eax must be preseerved)
  489. ;
  490. ; #define KiLeaveCriticalRegion() { \
  491. ; PKTHREAD Thread; \
  492. ; Thread = KeGetCurrentThread(); \
  493. ; if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \
  494. ; (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \
  495. ; &Thread->ApcState.ApcListHead[KernelMode])) { \
  496. ; Thread->ApcState.KernelApcPending = TRUE; \
  497. ; KiRequestSoftwareInterrupt(APC_LEVEL); \
  498. ; } \
  499. ; }
  500. ;
  501. mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread()
  502. inc WORD PTR [ebx].ThKernelApcDisable
  503. jz HmgShareLock_LeaveCriticalRegion
  504. HmgShareLock_Done::
  505. ; eax is set to the proper return value
  506. if DBG
  507. pop ebx ;Remove debug copy of objt
  508. pop ebx ;Remove debug copy of hobj
  509. endif
  510. pop ebx
  511. ret
  512. ; Roads less travelled...
  513. HmgShareLock_bad_handle_before_lock::
  514. pop ecx
  515. jmp HmgShareLock_bad_handle
  516. HmgShareLock_bad_handle_after_lock::
  517. mov [ecx].entry_ObjectOwner,ebx ;Unlock it
  518. HmgShareLock_bad_handle::
  519. if DBG
  520. ; Retrieve the debug copies of 'hobj' and 'objt' from where they
  521. ; were pushed on the stack:
  522. mov eax,[esp] ;objt
  523. mov ecx,[esp+4] ;hobj
  524. ; Call a debug routine that prints a warning, complete with
  525. ; the name of the owning process, handle value, and expected type.
  526. stdCall _HmgPrintBadHandle,<ecx,eax>
  527. endif
  528. xor eax,eax
  529. jmp HmgShareLock_incAPC
  530. HmgShareLock_delay::
  531. push ecx
  532. push edx
  533. mov eax,_gpLockShortDelay
  534. stdCall _KeDelayExecutionThread,<KernelMode,0,eax>
  535. pop edx
  536. pop ecx
  537. jmp HmgShareLock_resume
  538. HmgShareLock_LeaveCriticalRegion::
  539. lea ecx,[ebx].ThApcState+AsApcListHead
  540. mov edx,[ecx].LsFlink
  541. cmp ecx,edx
  542. jne HmgShareLock_CallInterrupt
  543. if DBG
  544. pop ebx ;Remove debug copy of objt
  545. pop ebx ;Remove debug copy of hobj
  546. endif
  547. pop ebx
  548. ret
  549. HmgShareLock_CallInterrupt::
  550. lea ecx,[ebx].ThApcState
  551. mov BYTE PTR [ecx].AsKernelApcPending,1
  552. push eax
  553. mov ecx,APC_LEVEL
  554. fstCall HalRequestSoftwareInterrupt
  555. pop eax
  556. jmp HmgShareLock_Done
  557. @HmgShareLock@8 endp
  558. ;------------------------------Public-Routine------------------------------;
  559. ; HmgIncrementShareReferenceCount (pobj)
  560. ;
  561. ;
  562. ; Increment shared reference count, no checking
  563. ;
  564. ; Input:
  565. ; EAX -- scratch
  566. ; ECX -- pobj
  567. ;
  568. ; Returns:
  569. ; EAX = pointer to referenced object
  570. ;
  571. ; Error Return:
  572. ; EAX = 0, No error logged.
  573. ;
  574. ;--------------------------------------------------------------------------;
  575. public @HmgIncrementShareReferenceCount@4
  576. @HmgIncrementShareReferenceCount@4 proc near
  577. push ebx ;Preserve register in call
  578. push ecx ;Stash pobj for later
  579. ; KeEnterCriticalRegion
  580. ; KeGetCurrentThread()->KernelApcDisable -= 1;
  581. mov ebx,fs:[PcPrcbData].PbCurrentThread ;eax -> KeGetCurrentThread()
  582. dec WORD PTR [ebx].ThKernelApcDisable
  583. mov ecx, [ecx]
  584. and ecx,INDEX_MASK
  585. shl ecx,4
  586. .errnz size ENTRY - 16
  587. add ecx,_gpentHmgr ;ecx -> Entry
  588. HmgIncrementShareReferenceCount_resume::
  589. mov eax,[ecx].entry_ObjectOwner
  590. mov ebx,[ecx].entry_ObjectOwner
  591. and eax,NOT OBJECTOWNER_LOCK
  592. or ebx,OBJECTOWNER_LOCK
  593. .486
  594. Lock7:
  595. lock cmpxchg [ecx].entry_ObjectOwner,ebx
  596. .386
  597. mov ebx,eax ;Remember unlock value
  598. jnz HmgIncrementShareReferenceCount_delay
  599. ; The handle is now locked
  600. mov eax,[ecx].entry_einfo ;Get pointer to object
  601. inc DWORD PTR [eax].object_ulShareCount
  602. mov [ecx].entry_ObjectOwner,ebx ;Unlock it
  603. HmgIncrementShareReferenceCount_incAPC::
  604. ; KiLeaveCriticalRegion (eax must be preseerved)
  605. ;
  606. ; #define KiLeaveCriticalRegion() { \
  607. ; PKTHREAD Thread; \
  608. ; Thread = KeGetCurrentThread(); \
  609. ; if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \
  610. ; (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \
  611. ; &Thread->ApcState.ApcListHead[KernelMode])) { \
  612. ; Thread->ApcState.KernelApcPending = TRUE; \
  613. ; KiRequestSoftwareInterrupt(APC_LEVEL); \
  614. ; } \
  615. ; }
  616. ;
  617. mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread()
  618. inc WORD PTR [ebx].ThKernelApcDisable
  619. jz HmgIncrementShareReferenceCount_LeaveCriticalRegion
  620. HmgIncrementShareReferenceCount_Done::
  621. ; eax is set to the proper return value
  622. pop ecx
  623. pop ebx
  624. ret
  625. ; Roads less travelled...
  626. HmgIncrementShareReferenceCount_delay::
  627. push ecx
  628. mov eax,_gpLockShortDelay
  629. stdCall _KeDelayExecutionThread,<KernelMode,0,eax>
  630. pop ecx
  631. jmp HmgIncrementShareReferenceCount_resume
  632. HmgIncrementShareReferenceCount_LeaveCriticalRegion::
  633. lea ecx,[ebx].ThApcState+AsApcListHead
  634. mov edx,[ecx].LsFlink
  635. cmp ecx,edx
  636. jne HmgIncrementShareReferenceCount_CallInterrupt
  637. pop ecx
  638. pop ebx
  639. ret
  640. HmgIncrementShareReferenceCount_CallInterrupt::
  641. lea ecx,[ebx].ThApcState
  642. mov BYTE PTR [ecx].AsKernelApcPending,1
  643. push eax
  644. mov ecx,APC_LEVEL
  645. fstCall HalRequestSoftwareInterrupt
  646. pop eax
  647. jmp HmgIncrementShareReferenceCount_Done
  648. @HmgIncrementShareReferenceCount@4 endp
  649. ;------------------------------Public-Routine------------------------------;
  650. ; HmgDecrementShareReferenceCount (pobj)
  651. ;
  652. ;
  653. ; Decrement shared reference count, no checking
  654. ;
  655. ; Input:
  656. ; EAX -- scratch
  657. ; ECX -- pobj
  658. ;
  659. ; Returns:
  660. ;
  661. ; Error Return:
  662. ; EAX = 0, No error logged.
  663. ;
  664. ;--------------------------------------------------------------------------;
  665. public @HmgDecrementShareReferenceCount@4
  666. @HmgDecrementShareReferenceCount@4 proc near
  667. push ebx ;Preserve register in call
  668. push ecx ;Stash pobj for later
  669. ; KeEnterCriticalRegion
  670. ; KeGetCurrentThread()->KernelApcDisable -= 1;
  671. mov ebx,fs:[PcPrcbData].PbCurrentThread ;eax -> KeGetCurrentThread()
  672. dec WORD PTR [ebx].ThKernelApcDisable
  673. mov ecx, [ecx]
  674. and ecx,INDEX_MASK
  675. shl ecx,4
  676. .errnz size ENTRY - 16
  677. add ecx,_gpentHmgr ;ecx -> Entry
  678. HmgDecrementShareReferenceCount_resume::
  679. mov eax,[ecx].entry_ObjectOwner
  680. mov ebx,[ecx].entry_ObjectOwner
  681. and eax,NOT OBJECTOWNER_LOCK
  682. or ebx,OBJECTOWNER_LOCK
  683. .486
  684. Lock8:
  685. lock cmpxchg [ecx].entry_ObjectOwner,ebx
  686. .386
  687. mov ebx,eax ;Remember unlock value
  688. jnz HmgDecrementShareReferenceCount_delay
  689. ; The handle is now locked
  690. mov edx,[ecx].entry_einfo ;Get pointer to object
  691. mov eax, [edx].object_ulShareCount
  692. dec DWORD PTR [edx].object_ulShareCount
  693. mov [ecx].entry_ObjectOwner,ebx ;Unlock it
  694. HmgDecrementShareReferenceCount_incAPC::
  695. ; KiLeaveCriticalRegion (eax must be preseerved)
  696. ;
  697. ; #define KiLeaveCriticalRegion() { \
  698. ; PKTHREAD Thread; \
  699. ; Thread = KeGetCurrentThread(); \
  700. ; if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \
  701. ; (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \
  702. ; &Thread->ApcState.ApcListHead[KernelMode])) { \
  703. ; Thread->ApcState.KernelApcPending = TRUE; \
  704. ; KiRequestSoftwareInterrupt(APC_LEVEL); \
  705. ; } \
  706. ; }
  707. ;
  708. mov ebx,fs:[PcPrcbData].PbCurrentThread ;ebx -> KeGetCurrentThread()
  709. inc WORD PTR [ebx].ThKernelApcDisable
  710. jz HmgDecrementShareReferenceCount_LeaveCriticalRegion
  711. HmgDecrementShareReferenceCount_Done::
  712. ; eax is set to the proper return value
  713. pop ecx
  714. pop ebx
  715. ret
  716. ; Roads less travelled...
  717. HmgDecrementShareReferenceCount_delay::
  718. push ecx
  719. mov eax,_gpLockShortDelay
  720. stdCall _KeDelayExecutionThread,<KernelMode,0,eax>
  721. pop ecx
  722. jmp HmgDecrementShareReferenceCount_resume
  723. HmgDecrementShareReferenceCount_LeaveCriticalRegion::
  724. lea ecx,[ebx].ThApcState+AsApcListHead
  725. mov edx,[ecx].LsFlink
  726. cmp ecx,edx
  727. jne HmgDecrementShareReferenceCount_CallInterrupt
  728. pop ecx
  729. pop ebx
  730. ret
  731. HmgDecrementShareReferenceCount_CallInterrupt::
  732. lea ecx,[ebx].ThApcState
  733. mov BYTE PTR [ecx].AsKernelApcPending,1
  734. push eax
  735. mov ecx,APC_LEVEL
  736. fstCall HalRequestSoftwareInterrupt
  737. pop eax
  738. jmp HmgDecrementShareReferenceCount_Done
  739. @HmgDecrementShareReferenceCount@4 endp
  740. _TEXT ends
  741. endif
  742. end