Source code of Windows XP (NT5)
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.

2300 lines
79 KiB

  1. TITLE GINTERF - Global Memory Manager interface procedures
  2. .xlist
  3. include kernel.inc
  4. include pdb.inc
  5. include tdb.inc
  6. include newexe.inc
  7. ifdef WOW
  8. include wow.inc
  9. include wowkrn.inc
  10. include vint.inc
  11. include wowcmpat.inc
  12. GMEMSTATUS_block STRUC
  13. dwLength dd ? ;/* size in bytes of MEMORYSTATUS structure */
  14. dwMemoryLoad dd ? ;/* percent of memory being used */
  15. dwTotalPhys dd ? ;/* total bytes of physical memory */
  16. dwAvailPhys dd ? ;/* unallocated bytes of physical memory */
  17. dwTotalPageFile dd ? ;/* total bytes of paging file */
  18. dwAvailPageFile dd ? ;/* unallocated bytes of paging file */
  19. dwTotalVirtual dd ? ;/* total user bytes of virtual address space */
  20. dwAvailVirtual dd ? ;/* unallocated user bytes of virtual address space */
  21. GMEMSTATUS_block ENDS
  22. endif
  23. .list
  24. .386p
  25. include protect.inc
  26. CheckHeap MACRO name
  27. local a
  28. if KDEBUG
  29. extrn CheckGlobalHeap :near
  30. call CheckGlobalHeap
  31. jnc short a
  32. or ax,ERR_GMEM
  33. xor bx,bx
  34. kerror <>,<&name: Invalid global heap>,dx,bx
  35. a:
  36. endif
  37. endm
  38. ifdef WOW
  39. externFP WowCursorIconOp
  40. externFP GlobalMemoryStatus
  41. externFP WowDdeFreeHandle
  42. externFP FindAndReleaseDib
  43. externNP MyGetAppWOWCompatFlags
  44. endif
  45. externW pStackTop
  46. externW pStackMin
  47. externW pStackBot
  48. DataBegin
  49. externB Kernel_Flags
  50. externB fBooting
  51. externW hGlobalHeap
  52. externW pGlobalHeap
  53. externW curTDB
  54. externW loadTDB
  55. externW hExeHead
  56. externW WinFlags
  57. GSS_SI dw 0
  58. GSS_DS dw 0
  59. GSS_RET dd 0
  60. DataEnd
  61. sBegin CODE
  62. assumes CS,CODE
  63. if SDEBUG
  64. externNP DebugFreeSegment
  65. endif
  66. externNP galloc
  67. externNP grealloc
  68. externNP gfree
  69. externNP glock
  70. externNP gunlock
  71. externNP gfreeall
  72. externNP galign
  73. externNP gcompact
  74. externNP gmovebusy
  75. externNP gsearch
  76. externNP genter
  77. externNP gleave
  78. externNP gavail
  79. externNP glrutop
  80. externNP glrubot
  81. externNP glrudel
  82. externNP glruadd
  83. externNP gmarkfree
  84. externNP ShrinkHeap
  85. externNP HackCheck
  86. externNP get_arena_pointer32
  87. externNP get_physical_address
  88. externNP pdref
  89. externNP alloc_arena_header
  90. externNP free_arena_header
  91. externNP PreAllocArena
  92. externNP MyGetAppCompatFlags
  93. externNP DPMIProc
  94. externW gdtdsc
  95. if ROM
  96. externNP GetOwner
  97. endif
  98. if KDEBUG
  99. externFP OutputDebugString
  100. ThisIsForTurboPascal:
  101. db "A program has attempted an invalid selector-to-handle conversion.",13,10,"Attempting to correct this error.",13,10,0
  102. endif
  103. if KDEBUG
  104. ifndef WOW
  105. externNP xhandle_norip
  106. endif
  107. ifdef ?CHECKMEM
  108. cProc CheckMem,<PUBLIC,NEAR>
  109. cBegin nogen
  110. or ax,ax
  111. jnz short cm_okay
  112. cmp [di].hi_check,di
  113. je short cm_okay
  114. kerror ERR_GMEM,<GlobalAlloc or ReAlloc failed>,di,cx
  115. xor ax,ax
  116. xor cx,cx
  117. xor dx,dx
  118. cm_okay:
  119. ret
  120. cEnd nogen
  121. endif
  122. endif
  123. cProc GetDefOwner,<PUBLIC,NEAR>
  124. cBegin nogen
  125. CheckKernelDS fs
  126. ReSetKernelDS fs
  127. mov cx,curTDB
  128. jcxz xxxx
  129. mov es,cx
  130. mov cx,loadTDB
  131. jcxz xxx
  132. mov es,cx
  133. xxx: mov cx,es:[TDB_PDB]
  134. inc cx
  135. xxxx: dec cx
  136. ret
  137. UnSetKernelDS fs
  138. cEnd nogen
  139. ;-----------------------------------------------------------------------;
  140. ; gbtop ;
  141. ; ;
  142. ; Converts a 32-bit byte count to a 16-bit paragraph count. ;
  143. ; ;
  144. ; Arguments: ;
  145. ; AX = allocation flags or -1 if called from GlobalCompact ;
  146. ; BX = stack address of 32-bit unsigned integer ;
  147. ; DX = handle being reallocated or zero ;
  148. ; DS:DI = address of GlobalInfo for global heap ;
  149. ; ;
  150. ; Returns: ;
  151. ; AX = updated allocation flags ;
  152. ; EBX = #bytes needed to contain that many bytes ;
  153. ; CX = owner value to use ;
  154. ; DX = handle being reallocated or zero ;
  155. ; ;
  156. ; Error Returns: ;
  157. ; ;
  158. ; Registers Preserved: ;
  159. ; ;
  160. ; Registers Destroyed: ;
  161. ; ;
  162. ; Calls: ;
  163. ; ;
  164. ; History: ;
  165. ; ;
  166. ; Wed Dec 03, 1986 10:20:01p -by- David N. Weise [davidw] ;
  167. ; Added this nifty comment block. ;
  168. ;-----------------------------------------------------------------------;
  169. assumes ds,nothing
  170. assumes es,nothing
  171. cProc gbtop,<PUBLIC,NEAR>
  172. cBegin nogen
  173. CheckKernelDS fs
  174. ReSetKernelDS fs
  175. mov ebx, dword ptr ss:[bx]
  176. add ebx, 15
  177. jc short gbtop1
  178. and bl, not 15 ; Round to 16 byte boundary
  179. cmp ebx, (16*1020*1024) ; Too big?
  180. jbe short gbtop2 ; no.
  181. gbtop1:
  182. mov ebx, 07FFFFFFFh ; Make it a ridiculous value
  183. gbtop2:
  184. inc ax
  185. jnz short gbtop2a
  186. jmp gbtopx ; All done if called from GlobalCompact
  187. gbtop2a:
  188. dec ax
  189. mov cx, [bp].savedCS
  190. push eax
  191. if ROM
  192. push fs ; trashes registers!
  193. push ebx
  194. cCall GetOwner, <cx>
  195. pop ebx
  196. pop fs
  197. mov si, ax
  198. else
  199. cCall get_arena_pointer32,<cx>
  200. mov esi,eax
  201. endif
  202. pop eax
  203. mov cx,hExeHead ; CX = KERNEL exe header
  204. cmp fBooting,0 ; Done booting?
  205. jne short gbtop3 ; No, must be KERNEL allocating then
  206. if ROM
  207. cmp cx, si
  208. else
  209. cmp cx,ds:[esi].pga_owner ; Is the KERNEL calling us?
  210. endif
  211. je short gbtop3 ; Yes, let him party
  212. and ax,not GA_INTFLAGS ; No, then cant use these flags
  213. and al, NOT GA_ALLOCHIGH
  214. if ROM
  215. mov es, si
  216. else
  217. mov es,ds:[esi].pga_owner ; ES -> module database
  218. endif
  219. cmp es:[di].ne_magic,NEMAGIC; Valid?
  220. jne short gbtop2b ; No
  221. test es:[di].ne_flags,NENOTP ; Yes, is it an app?
  222. jnz short gbtop3 ; No, don't force it moveable
  223. gbtop2b:
  224. or al, GA_MOVEABLE ; Force it moveable
  225. gbtop3:
  226. mov cl,GA_SEGTYPE ; Isolate segment type bits in CL
  227. and cl,al
  228. mov [di].gi_cmpflags,al ; Save flags for gcompact
  229. and [di].gi_cmpflags,CMP_FLAGS
  230. or [di].gi_cmpflags, COMPACT_ALLOC ; Not a call from GlobalCompact
  231. or dx, dx ; ReAllocating?
  232. jnz short gbtop4 ; Yes, allow low
  233. test al,GA_MOVEABLE ; Is this a moveable request?
  234. jz short gbtop4 ; No, then go allocate low
  235. test cl,GA_DISCCODE ; Yes, is this discardable code?
  236. jz short gbtop4 ; Yes, then allocate high
  237. or al,GA_ALLOCHIGH ; No, then allocate low
  238. or [di].gi_cmpflags,GA_ALLOCHIGH
  239. gbtop4:
  240. push ax ; Under Win1.0x ANY bit in 0Fh meant
  241. mov al,HE_DISCARDABLE ; make discardable.
  242. and ah,al ; Under Win2.0x ONLY 01h or 0Fh means
  243. cmp ah,al ; discardable.
  244. pop ax
  245. jnz short gbtop4a
  246. and ah,not HE_DISCARDABLE ; Yes, convert to boolean value
  247. or ah,GA_DISCARDABLE
  248. gbtop4a:
  249. gbtop4b:
  250. and ah,NOT GA_SEGTYPE ; Clear any bogus flags
  251. or ah,cl ; Copy segment type bits
  252. test ah,GA_SHAREABLE ; Shared memory request?
  253. jz GetDefOwner ; No, default action
  254. if ROM
  255. mov cx, si ; the code below confuses me a little
  256. else
  257. mov cx,[bp].savedCS ; Yes, make owner same as
  258. push eax
  259. cCall get_arena_pointer32,<cx>
  260. cmp esi,eax
  261. je short @F
  262. int 3
  263. @@:
  264. pop eax
  265. mov cx,ds:[esi].pga_owner ; owner of calling code segment
  266. endif
  267. gbtopx:
  268. ret
  269. UnSetKernelDS fs
  270. cEnd nogen
  271. ; The remainder of this file implements the exported interface to the
  272. ; global memory manager. A summary follows:
  273. ; HANDLE far PASCAL GlobalAlloc( WORD, DWORD );
  274. ; HANDLE far PASCAL GlobalReAlloc( HANDLE, DWORD, WORD );
  275. ; HANDLE far PASCAL GlobalFree( HANDLE );
  276. ; HANDLE far PASCAL GlobalFreeAll( WORD );
  277. ; char far * far PASCAL GlobalLock( HANDLE );
  278. ; BOOL far PASCAL GlobalUnlock( HANDLE );
  279. ; DWORD far PASCAL GlobalSize( HANDLE );
  280. ; DWORD far PASCAL GlobalCompact( DWORD );
  281. ; #define GlobalDiscard( h ) GlobalReAlloc( h, 0L, GMEM_MOVEABLE )
  282. ; HANDLE far PASCAL GlobalHandle( WORD );
  283. ; HANDLE far PASCAL LockSegment( WORD );
  284. ; HANDLE far PASCAL UnlockSegment( WORD );
  285. cProc IGlobalAlloc,<PUBLIC,FAR>
  286. parmW flags
  287. parmD nbytes
  288. cBegin
  289. GENTER32 ; About to modify memory arena
  290. cCall MyGetAppCompatFlags ; Ignore the NODISCARD flag
  291. test al, GACF_IGNORENODISCARD ; for selected modules
  292. mov ax, flags
  293. jz short @f
  294. call IsKernelCalling ; needs caller's CS @ [bp+4]
  295. jz short @f ; skip hack if kernel calling us
  296. and al, NOT GA_NODISCARD
  297. @@:
  298. xor dx,dx ; No handle
  299. lea bx,nbytes ; Convert requested bytes to paragraphs
  300. call gbtop ; ... into BX
  301. call galloc
  302. ifdef ?CHECKMEM
  303. if KDEBUG
  304. call CheckMem
  305. endif
  306. endif
  307. CheckHeap GlobalAlloc
  308. GLEAVE32
  309. if kdebug
  310. or ax, ax
  311. jnz @F
  312. push ax
  313. push bx
  314. mov bx, seg_nbytes
  315. mov ax, off_nbytes
  316. krDebugOut <DEB_TRACE or DEB_krMemMan>, "GlobalAlloc(#bx#AX) failed for %ss2"
  317. pop bx
  318. pop ax
  319. @@:
  320. endif
  321. cEnd
  322. cProc IGlobalReAlloc,<PUBLIC,FAR>
  323. parmW handle
  324. parmD nbytes
  325. parmW rflags
  326. cBegin
  327. ;
  328. ; Does this thing have any ring bits or LDT bit? If not, then it
  329. ; could be a selector incorrectly converted to a handle.
  330. ;
  331. test byte ptr handle,7
  332. jnz SHORT @F
  333. if KDEBUG
  334. Trace_Out "GlobalReAlloc:"
  335. push seg ThisIsForTurboPascal
  336. push offset ThisIsForTurboPascal
  337. cCall OutputDebugString
  338. int 3
  339. endif
  340. dec handle
  341. @@:
  342. GENTER32 ; About to modify memory arena
  343. cCall MyGetAppCompatFlags ; Ignore the NODISCARD flag
  344. test al, GACF_IGNORENODISCARD ; for selected modules
  345. mov ax, rflags
  346. jz short @f
  347. call IsKernelCalling ; needs caller's CS @ [bp+4]
  348. jz short @f ; skip hack if kernel calling us
  349. and al, NOT GA_NODISCARD
  350. @@:
  351. #ifdef WOW
  352. push ax
  353. ; check for suspicious dib memory
  354. mov dx, handle
  355. call pdref
  356. ; check if the obj is locked
  357. or ch,ch
  358. jz short gr_proceed
  359. ; here, check for phantom flag... this might mean
  360. ; it's dib sec
  361. test cl, GAH_PHANTOM
  362. jz short gr_proceed
  363. ; if we are here - mem object is locked and boogie flag is set
  364. ; sufficient reason to check with wow32 to see if this is
  365. ; pesky dib section
  366. cCall FindAndReleaseDib, <handle, FUN_GLOBALREALLOC>
  367. gr_proceed:
  368. pop ax
  369. #endif
  370. mov dx,handle
  371. ; mov ax,rflags
  372. lea bx,nbytes ; Convert requested bytes to paragraphs
  373. call gbtop ; ... into BX
  374. call grealloc
  375. gr_done:
  376. CheckHeap GlobalReAlloc
  377. GLEAVE32
  378. cEnd
  379. cProc DiscardTheWorld,<PUBLIC,NEAR>
  380. cBegin
  381. GENTER32
  382. mov [di].gi_cmpflags, GA_DISCCODE+COMPACT_ALLOC
  383. mov edx, -1
  384. call gcompact
  385. GLEAVE32
  386. cEnd
  387. ; Returns with Z flag set if ss:[bp+4] is a kernel code segment selector.
  388. ; Uses: DX, flags.
  389. cProc IsKernelCalling,<PUBLIC,NEAR>
  390. cBegin nogen
  391. mov dx, [bp+4] ; CS of GlobalAlloc caller
  392. cmp dx, IGROUP
  393. jz @f
  394. cmp dx, _NRESTEXT
  395. jz @f
  396. cmp dx, _MISCTEXT
  397. @@:
  398. ret
  399. cEnd nogen
  400. ;-----------------------------------------------------------------------;
  401. ; GlobalFree ;
  402. ; ;
  403. ; Frees the given object. If the object lives in someone elses banks ;
  404. ; then the argument MUST be a handle entry. ;
  405. ; ;
  406. ; Arguments: ;
  407. ; parmW handle ;
  408. ; ;
  409. ; Returns: ;
  410. ; ;
  411. ; Error Returns: ;
  412. ; ;
  413. ; Registers Preserved: ;
  414. ; ;
  415. ; Registers Destroyed: ;
  416. ; ;
  417. ; Calls: ;
  418. ; ;
  419. ; History: ;
  420. ; ;
  421. ; Wed 26-Apr-1989 15:33:18 -by- David N. Weise [davidw] ;
  422. ; Added the zero'ing of ES on exit. ;
  423. ; ;
  424. ; Sat Apr 25, 1987 10:23:13p -by- David N. Weise [davidw] ;
  425. ; Added support for EMS and added this nifty comment block. ;
  426. ;-----------------------------------------------------------------------;
  427. assumes ds,nothing
  428. assumes es,nothing
  429. cProc IGlobalFree,<PUBLIC,FAR>
  430. parmW handle
  431. ifdef WOW
  432. DsOnStack equ [bp][-2]
  433. endif
  434. ; if you add any local params or make this nogen or something similar,
  435. ; the references to [bp][-2] to access DS on stack will need to change!
  436. cBegin
  437. GENTER32 ; About to modify memory arena
  438. mov es, di ; We may be freeing what is in ES
  439. xor ax,ax ; In case handle = 0.
  440. mov dx,handle
  441. or dx,dx
  442. jnz @F
  443. jmp nothing_to_free
  444. @@:
  445. ;
  446. ; Does this thing have any ring bits or LDT bit? If not, then it
  447. ; could be a selector incorrectly converted to a handle.
  448. ;
  449. test dl,7
  450. jnz SHORT @F
  451. if KDEBUG
  452. Trace_Out "GlobalFree:"
  453. push seg ThisIsForTurboPascal
  454. push offset ThisIsForTurboPascal
  455. cCall OutputDebugString
  456. int 3
  457. endif
  458. dec dx
  459. @@:
  460. push dx
  461. call pdref ; returns dx=handle, ax=selector
  462. pushf ; save pdref Z flag return
  463. ifdef WOW
  464. ;
  465. ; [bp][-2] has been changed to DsOnStack
  466. ;
  467. endif
  468. cmp ax,DsOnStack ; Are we about to free the DS on
  469. jz short yup ; the stack and GP?
  470. cmp dx,DsOnStack
  471. jnz short nope
  472. yup: xor dx,dx ; Yup, zero DS image on stack...
  473. mov DsOnStack,dx
  474. nope:
  475. popf ; flags from pdref, Z set if discarded
  476. pop dx
  477. jz @f ; discarded can be freed, but has
  478. ; no arena pointer
  479. or esi, esi ; Handle invalid if arena ptr = 0
  480. jz nothing_to_free
  481. @@:
  482. ifdef WOW
  483. or ch,ch
  484. jz short gf_checkgicon
  485. ; here, check for phantom flag...
  486. test cl, GAH_PHANTOM
  487. jz gf_checkgicon
  488. ; sufficient reason to check with wow32 to see if this is
  489. ; pesky dib section
  490. push dx ; dx is the only one that needs saving
  491. cCall FindAndReleaseDib, <dx, FUN_GLOBALFREE>
  492. or ax, ax ; if true, then just bail out, else free...
  493. pop dx
  494. jz gf_checkgicon
  495. ; now call the pdref again... as dx is set to selector
  496. call pdref ; ret handle - also ok
  497. jmps gf_notdib ; not a dib anymore...
  498. gf_checkgicon:
  499. endif
  500. if KDEBUG
  501. test dl, GA_FIXED
  502. jnz short freeo
  503. or ch,ch ; Debugging check for count underflow
  504. jz short freeo
  505. pushad
  506. xor bx,bx
  507. kerror ERR_GMEMUNLOCK,<GlobalFree: freeing locked object>,bx,handle
  508. popad
  509. freeo:
  510. endif
  511. ifdef WOW
  512. test cl, GAH_CURSORICON ; call to pdref above sets cl
  513. ; Note: GAH_CURSORICON is also used for Free'ing
  514. ; Accelerators - a-craigj
  515. jz gf_wowdde
  516. push ax ; save
  517. push bx
  518. push dx
  519. push es
  520. push fs ; fs needs saving
  521. push handle
  522. push FUN_GLOBALFREE
  523. call WowCursorIconOp
  524. or ax, ax ; if TRUE 'free' else 'dont free, fake success'
  525. pop fs
  526. pop es
  527. pop dx
  528. pop bx
  529. pop ax ; restore
  530. jnz gf_notglobalicon
  531. xor ax, ax ; fake success
  532. xor cx, cx
  533. jmps nothing_to_free
  534. gf_wowdde:
  535. test cl, GAH_WOWDDEFREEHANDLE
  536. jz gf_noticon
  537. push ax
  538. push bx
  539. push dx
  540. push es ; save these
  541. push fs
  542. push handle
  543. call WowDdeFreeHandle
  544. or ax, ax ; if TRUE 'free' else 'dont free, fake success'
  545. pop fs
  546. pop es
  547. pop dx
  548. pop bx
  549. pop ax
  550. jnz gf_notglobalicon
  551. xor ax, ax ; fake success
  552. xor cx, cx
  553. jmps nothing_to_free
  554. gf_notdib:
  555. gf_notglobalicon:
  556. gf_noticon:
  557. endif
  558. xor cx,cx ; Dont check owner field
  559. call gfree
  560. nothing_to_free:
  561. CheckHeap GlobalFree
  562. GLEAVE32
  563. cEnd
  564. ;-----------------------------------------------------------------------;
  565. ; GlobalFreeAll ;
  566. ; ;
  567. ; Frees all of the global objects belonging to the given owner. ;
  568. ; ;
  569. ; Arguments: ;
  570. ; parmW id ;
  571. ; ;
  572. ; Returns: ;
  573. ; ;
  574. ; Error Returns: ;
  575. ; ;
  576. ; Registers Preserved: ;
  577. ; ;
  578. ; Registers Destroyed: ;
  579. ; ;
  580. ; Calls: ;
  581. ; ;
  582. ; History: ;
  583. ; ;
  584. ; Wed 26-Apr-1989 15:33:18 -by- David N. Weise [davidw] ;
  585. ; Added the zero'ing of ES on exit. ;
  586. ; ;
  587. ; Sat Apr 25, 1987 10:23:13p -by- David N. Weise [davidw] ;
  588. ; Added support for EMS and added this nifty comment block. ;
  589. ;-----------------------------------------------------------------------;
  590. cProc GlobalFreeAll,<PUBLIC,FAR>
  591. parmW id
  592. cBegin
  593. GENTER32 ; About to modify memory arena
  594. mov es, di ; We may be freeing what is in ES
  595. mov dx,id ; Get id to match with
  596. or dx,dx ; Is it zero?
  597. jnz short all1 ; No, continue
  598. call GetDefOwner ; Yes, CX = default task owner to free
  599. mov dx,cx
  600. all1:
  601. if SDEBUG
  602. mov esi,[di].phi_first ; ES:DI points to first arena entry
  603. mov cx,[di].hi_count ; CX = #entries in the arena
  604. all2:
  605. cmp ds:[esi].pga_owner,dx
  606. jne short all3
  607. mov ax, ds:[esi].pga_handle
  608. Handle_To_Sel al
  609. push cx
  610. push dx
  611. cCall DebugFreeSegment,<ax,0>
  612. pop dx
  613. pop cx
  614. all3:
  615. mov esi,ds:[esi].pga_next ; Move to next block
  616. loop all2 ; Back for more if there (may go extra times
  617. ; because of coalescing, but no great whoop)
  618. endif
  619. call gfreeall
  620. ; REALLY free the id selector. MSTEST setup depends on this.
  621. pushf
  622. push ax
  623. push bx
  624. push es
  625. push di
  626. mov di,id
  627. and di,0FFF8h
  628. mov es,gdtdsc
  629. push es:[di]
  630. push es:[di + 2]
  631. push es:[di + 4]
  632. push es:[di + 6]
  633. mov word ptr es:[di],0
  634. mov word ptr es:[di + 2],0
  635. mov word ptr es:[di + 4],0
  636. mov word ptr es:[di + 6],0
  637. mov bx,id
  638. DPMICALL 000Ch
  639. pop es:[di + 6]
  640. pop es:[di + 4]
  641. pop es:[di + 2]
  642. pop es:[di]
  643. pop di
  644. pop es
  645. pop bx
  646. pop ax
  647. popf
  648. gf_done:
  649. CheckHeap GlobalFreeAll
  650. GLEAVE32
  651. cEnd
  652. ;-----------------------------------------------------------------------;
  653. ; xhandle ;
  654. ; ;
  655. ; Returns the handle for a global segment. ;
  656. ; ;
  657. ; Arguments: ;
  658. ; Stack = sp -> near return return address ;
  659. ; sp+2 -> far return return address of caller ;
  660. ; sp+6 -> segment address parameter ;
  661. ; ;
  662. ; Returns: ;
  663. ; Old DS,DI have been pushed on the stack ;
  664. ; ;
  665. ; ZF= 1 if fixed segment. ;
  666. ; AX = handle ;
  667. ; ;
  668. ; ZF = 0 ;
  669. ; AX = handle ;
  670. ; BX = pointer to handle table entry ;
  671. ; CX = flags and count word from handle table ;
  672. ; DX = segment address ;
  673. ; ES:DI = arena header of object ;
  674. ; DS:DI = master object segment address ;
  675. ; ;
  676. ; Error Returns: ;
  677. ; AX = 0 if invalid segment address ;
  678. ; ZF = 1 ;
  679. ; ;
  680. ; Registers Preserved: ;
  681. ; ;
  682. ; Registers Destroyed: ;
  683. ; ;
  684. ; Calls: ;
  685. ; ;
  686. ; History: ;
  687. ; ;
  688. ; Thu Oct 16, 1986 02:40:08p -by- David N. Weise [davidw] ;
  689. ; Added this nifty comment block. ;
  690. ;-----------------------------------------------------------------------;
  691. cProc xhandle,<PUBLIC,NEAR>
  692. cBegin nogen
  693. pop dx ; Get near return address
  694. mov bx,sp ; Get seg parameter from stack
  695. mov ax,ss:[bx+4]
  696. cmp ax,-1 ; Is it -1?
  697. jnz short xh1
  698. mov ax,ds ; Yes, use callers DS
  699. xh1: inc bp
  700. push bp
  701. mov bp,sp
  702. push ds ; Save DS:DI
  703. push edi
  704. push esi
  705. SetKernelDS FS
  706. mov ds,pGlobalHeap ; Point to master object
  707. xor edi,edi
  708. inc [di].gi_lrulock
  709. push dx
  710. mov dx,ax
  711. call pdref
  712. xchg dx,ax ; get seg address in DX
  713. jz short xhandle_ret ; invalid or discarded handle
  714. test al, GA_FIXED
  715. jnz short xhandle_fixed
  716. or ax, ax
  717. jmps xhandle_ret
  718. xhandle_fixed:
  719. xor bx, bx ; Set ZF
  720. xhandle_ret:
  721. ret
  722. UnSetKernelDS FS
  723. cEnd nogen
  724. cProc GlobalHandleNorip,<PUBLIC,FAR>
  725. ; parmW seg
  726. cBegin nogen
  727. ifdef WOW
  728. call xhandle
  729. else
  730. if KDEBUG
  731. call xhandle_norip
  732. else ; !WOW
  733. call xhandle
  734. endif
  735. endif ; !WOW
  736. mov ebx, esi
  737. jmp xhandlex
  738. cEnd nogen
  739. cProc IGlobalHandle,<PUBLIC,FAR>
  740. parmW selector
  741. cBegin
  742. cCall MyLock,<selector>
  743. xchg ax, dx
  744. cEnd
  745. cProc MyLock,<PUBLIC,NEAR>
  746. ; parmW seg
  747. cBegin nogen
  748. mov bx, sp
  749. xor ax, ax ; In case LAR fails
  750. xor dx, dx
  751. lar ax, ss:[bx+2]
  752. jnz SHORT ML_End ; LAR failed, get out
  753. test ah, DSC_PRESENT
  754. jz short @F
  755. push ds ; Do quick conversion for present
  756. SetKernelDS ; selector
  757. mov ds, pGlobalHeap
  758. UnSetKernelDS
  759. cCall get_arena_pointer32,<ss:[bx+2]>
  760. or eax, eax
  761. jnz SHORT got_arena_pointer
  762. ;** Fix for bug #9106 and (I think) #9102
  763. ife ROM
  764. ;** If we get here, it's only because get_arena_pointer failed.
  765. ;** This happens with any non-heap selector.
  766. pop ds
  767. jmp SHORT ML_End ;Return NULL instead of GP faulting
  768. else
  769. ; in ROM, get-arena fails for ROM segments which do not have
  770. ; arena headers, so just assume this is the case and return the
  771. ; selector.
  772. ;
  773. mov ax, ss:[bx+2]
  774. jmps ml_ret
  775. endif
  776. got_arena_pointer:
  777. mov ax, ds:[eax].pga_handle
  778. ml_ret:
  779. pop ds
  780. mov dx, ax
  781. Handle_To_Sel al
  782. ML_End:
  783. ret 2
  784. @@:
  785. pop ax ; Convert to far call for xhandle
  786. push cs
  787. push ax
  788. call xhandle
  789. xchg ax, dx
  790. jmp xhandlex
  791. cEnd nogen
  792. cProc ILockSegment,<PUBLIC,FAR>
  793. ; parmW seg
  794. cBegin nogen
  795. call xhandle ; Get handle
  796. jnz ls5 ; Ignore invalid or discarded objects
  797. jmp xhandlex
  798. ls5:
  799. test cl,GA_DISCARDABLE
  800. jz short xhandlex
  801. call glock
  802. jmps xhandlex
  803. cEnd nogen
  804. cProc IGlobalFix,<PUBLIC,FAR>
  805. ; parmW seg
  806. cBegin nogen
  807. call xhandle ; Get handle
  808. jz short xhandlex ; Ignore invalid or discarded objects
  809. call glock
  810. jmps xhandlex
  811. cEnd nogen
  812. cProc IUnlockSegment,<PUBLIC,FAR>
  813. ; parmW seg
  814. cBegin nogen
  815. call xhandle ; Get handle
  816. jz short xhandlex ; Ignore invalid or discarded objects
  817. test cl,GA_DISCARDABLE
  818. jz short xhandlex
  819. call gunlock
  820. jmps xhandlex
  821. cEnd nogen
  822. cProc IGlobalUnfix,<PUBLIC,FAR>
  823. ; parmW seg
  824. cBegin nogen
  825. call xhandle ; Get handle
  826. jz short xhandlex ; Ignore invalid or discarded objects
  827. call gunlock
  828. jmps xhandlex
  829. cEnd nogen
  830. cProc IGlobalSize,<PUBLIC,FAR>
  831. ; parmW handle
  832. cBegin nogen
  833. call xhandle ; Call ghandle with handle in DX
  834. jnz short gs1 ; Continue if valid handle
  835. or dx,dx
  836. jnz short gs1
  837. xor ax,ax ; Return zero if invalid handle
  838. jmps xhandlex
  839. gs1:
  840. or esi, esi ; Can't be valid if arena ptr == 0
  841. jz gs2
  842. push eax
  843. mov eax, ds:[esi].pga_size
  844. shr eax, 4
  845. mov cx, ax ; Return number paragraphs in CX
  846. shr eax, 12
  847. mov dx, ax
  848. pop eax
  849. mov ax, word ptr ds:[esi].pga_size
  850. push ds
  851. push dx
  852. push ax
  853. cCall hackcheck,<handle>
  854. or ax,ax
  855. jz gsN
  856. pop ax
  857. pop dx
  858. mov ax,04000h
  859. xor dx,dx
  860. push dx
  861. push ax
  862. gsN:
  863. pop ax
  864. pop dx
  865. pop ds
  866. jmps xhandlex
  867. gs2:
  868. xor ax, ax
  869. xor dx, dx
  870. jmps xhandlex
  871. cEnd nogen
  872. cProc IGlobalFlags,<PUBLIC,FAR>
  873. ; parmW handle
  874. cBegin nogen
  875. call xhandle ; Call ghandle with handle in DX
  876. xchg cl,ch ; Return lock count in low half
  877. mov ax,cx ; Let caller do jcxz to test failure
  878. xhandlex:
  879. call gleave
  880. mov es, di ; don't return arbitrary selector
  881. mov fs, di
  882. pop esi
  883. pop edi
  884. pop ds
  885. pop bp
  886. dec bp
  887. ret 2
  888. cEnd nogen
  889. if 0
  890. cProc IGlobalLock,<PUBLIC,FAR>
  891. ; parmW handle
  892. cBegin nogen
  893. call xhandle ; Call ghandle with handle in DX
  894. jz short lock1 ; Ignore invalid or discarded objects
  895. if KDEBUG
  896. cmp ch,0FFh ; Debugging check for count overflow
  897. jne short lock0
  898. push bx
  899. push cx
  900. push dx
  901. xor cx,cx
  902. kerror ERR_GMEMLOCK,<GlobalLock: Object usage count overflow>,cx,bx
  903. pop dx
  904. pop cx
  905. pop bx
  906. lock0:
  907. endif
  908. test cl,GA_DISCARDABLE
  909. jz short lock1
  910. call glock ; Increment lock count
  911. lock1:
  912. xor ax,ax
  913. mov cx,dx
  914. xhandlex1:
  915. jmp short xhandlex
  916. cEnd nogen
  917. else
  918. cProc IGlobalLock,<PUBLIC,FAR>,<ds>
  919. parmW handle
  920. ifdef WOW
  921. localW gflags
  922. localW accword
  923. endif
  924. cBegin
  925. ifdef WOW
  926. mov gflags,0
  927. endif
  928. xor dx, dx ; Assume failure
  929. cmp handle, -1
  930. jne short @F
  931. mov handle, ds
  932. @@:
  933. lar eax, dword ptr handle
  934. shr eax, 8
  935. ifdef WOW
  936. mov accword, ax
  937. endif
  938. test al, DSC_PRESENT ; Is it present?
  939. jz short GL_exit
  940. mov dx, handle ; OK, will return something
  941. Handle_To_Sel dl ; Turn parameter into a selector
  942. ifndef WOW
  943. test ah, DSC_DISCARDABLE ; Is it discardable
  944. jz short GL_exit ; no, Lock is a nop
  945. endif
  946. SetKernelDS es
  947. mov ds, pGlobalHeap
  948. cCall get_arena_pointer32,<dx> ; Discardable, get its arena
  949. or eax, eax
  950. jz short GL_exit ; No arena, assume an alias
  951. ifdef WOW
  952. mov cl, ds:[eax].pga_flags
  953. mov byte ptr gflags, cl
  954. test accword, DSC_DISCARDABLE SHL 8
  955. jz GL_exit
  956. endif
  957. inc ds:[eax].pga_count ; Finally, do the lock
  958. if KDEBUG
  959. jnz short GL_exit ; Rip if we overflow
  960. push bx
  961. mov bx, handle
  962. xor cx,cx
  963. kerror ERR_GMEMLOCK,<GlobalLock: Object usage count overflow>,cx,bx
  964. pop bx
  965. endif
  966. UnSetKernelDS es
  967. GL_exit:
  968. ifdef WOW
  969. test gflags, GAH_CURSORICON
  970. jz GL_NotIcon
  971. push dx ; save
  972. push handle ; arg for CursorIconLockOp
  973. push FUN_GLOBALLOCK ; func id
  974. call WowCursorIconOp
  975. pop dx ; restore
  976. GL_NotIcon:
  977. endif
  978. xor ax, ax
  979. mov es, ax ; Clean out ES
  980. mov cx, dx ; HISTORY - someone probably does a jcxz
  981. cEnd
  982. endif
  983. cProc IGlobalUnlock,<PUBLIC,FAR>,<ds>
  984. parmW handle
  985. ifdef WOW
  986. localW gflags
  987. localW accword
  988. endif
  989. cBegin
  990. mov gflags,0
  991. cmp handle, -1
  992. jne short @F
  993. mov handle, ds
  994. @@:
  995. ;
  996. ; Does this thing have any ring bits or LDT bit? If not, then it
  997. ; could be a selector incorrectly converted to a handle.
  998. ;
  999. test byte ptr handle,7
  1000. jnz SHORT @F
  1001. if KDEBUG
  1002. Trace_Out "GlobalUnlock:"
  1003. push seg ThisIsForTurboPascal
  1004. push offset ThisIsForTurboPascal
  1005. cCall OutputDebugString
  1006. int 3
  1007. endif
  1008. dec handle
  1009. @@:
  1010. xor cx, cx ; Assume zero lock count
  1011. lar eax, dword ptr handle
  1012. shr eax, 8
  1013. ifdef WOW
  1014. mov accword, ax
  1015. endif
  1016. test al, DSC_PRESENT ; Is it present?
  1017. jz short GU_exit ; no, must be discarded, return 0:0
  1018. ifndef WOW
  1019. test ah, DSC_DISCARDABLE ; Is it discardable
  1020. jz short GU_exit ; no, Lock is a nop
  1021. endif
  1022. SetKernelDS es
  1023. mov ds, pGlobalHeap
  1024. cCall get_arena_pointer32,<handle> ; Discardable, get its arena
  1025. or eax, eax
  1026. jz short GU_exit ; No arena, assume an alias
  1027. ifdef WOW
  1028. push cx
  1029. mov cl,ds:[eax].pga_flags
  1030. mov byte ptr gflags, cl
  1031. pop cx
  1032. test accword, DSC_DISCARDABLE SHL 8
  1033. jz GU_exit
  1034. endif
  1035. mov cl, ds:[eax].pga_count ; Get current count
  1036. dec cl
  1037. cmp cl, 0FEh
  1038. jae short @F
  1039. dec ds:[eax].pga_count ; Finally, do the unlock
  1040. jmps GU_Exit
  1041. @@:
  1042. if KDEBUG
  1043. push bx ; then the count is wrong.
  1044. push dx
  1045. mov bx, handle
  1046. xor cx,cx
  1047. kerror ERR_GMEMUNLOCK,<GlobalUnlock: Object usage count underflow>,cx,bx
  1048. pop dx
  1049. pop bx
  1050. endif
  1051. xor cx, cx
  1052. UnSetKernelDS es
  1053. GU_exit:
  1054. ifdef WOW
  1055. test gflags, GAH_CURSORICON
  1056. jz GUL_NotIcon
  1057. push cx ; save
  1058. push handle ; arg for CursorIconLockOp
  1059. push FUN_GLOBALUNLOCK ; UnLocking
  1060. call WowCursorIconOp
  1061. pop cx ; restore
  1062. GUL_NotIcon:
  1063. endif
  1064. xor ax, ax
  1065. mov es, ax ; Clean out ES
  1066. mov ax, cx
  1067. ; Smalltalk V version 1.1 has a bug where they depend on dx containing
  1068. ; the handle as it did in 3.0. Sinc STalk is a 386 only app, this is
  1069. ; only put into the 386 kernel
  1070. mov dx, handle
  1071. cEnd
  1072. ;-----------------------------------------------------------------------;
  1073. ; GlobalWire ;
  1074. ; ;
  1075. ; Locks a moveable segment and moves it down as low as possible. ;
  1076. ; This is meant for people who are going to be locking an object ;
  1077. ; for a while and wish to be polite. It cannot work as a general ;
  1078. ; panacea, judgement is still called for in its use! ;
  1079. ; ;
  1080. ; Arguments: ;
  1081. ; WORD object handle ;
  1082. ; ;
  1083. ; Returns: ;
  1084. ; DWORD object address ;
  1085. ; ;
  1086. ; Error Returns: ;
  1087. ; ;
  1088. ; Registers Preserved: ;
  1089. ; ;
  1090. ; Registers Destroyed: ;
  1091. ; ;
  1092. ; Calls: ;
  1093. ; xhandle ;
  1094. ; gmovebusy ;
  1095. ; ;
  1096. ; History: ;
  1097. ; ;
  1098. ; Wed Dec 03, 1986 01:07:13p -by- David N. Weise [davidw] ;
  1099. ; Wrote it. ;
  1100. ;-----------------------------------------------------------------------;
  1101. cProc IGlobalWire,<PUBLIC,FAR>
  1102. ; parmW handle
  1103. cBegin nogen
  1104. if KDEBUG
  1105. push ds
  1106. SetKernelDS
  1107. cmp [fBooting], 0
  1108. jnz shutup
  1109. push bx
  1110. mov bx, sp
  1111. mov bx, ss:[bx+8]
  1112. krDebugOut <DEB_WARN OR DEB_KrMemMan>, "GlobalWire(#BX of %BX2) (try GlobalLock)"
  1113. pop bx
  1114. shutup:
  1115. pop ds
  1116. UnSetKernelDS
  1117. endif
  1118. call xhandle
  1119. jz short gw_done ; Ignore invalid or discarded objects
  1120. call gwire ; Copy it low if possible
  1121. inc ds:[esi].pga_count ; Lock it down.
  1122. test ds:[esi].pga_flags,GA_DISCCODE
  1123. jz short not_disccode
  1124. call glrudel
  1125. and ds:[esi].pga_flags,NOT GA_DISCCODE
  1126. not_disccode:
  1127. mov ax, ds:[esi].pga_handle
  1128. Handle_To_Sel al ; Return address.
  1129. gw_done:
  1130. mov dx,ax
  1131. xor ax,ax ; Make address SEG:OFF.
  1132. jmp xhandlex
  1133. cEnd nogen
  1134. cProc gwire,<PUBLIC,NEAR>
  1135. cBegin nogen
  1136. ReSetKernelDS fs
  1137. or Kernel_Flags[1],kf1_MEMORYMOVED
  1138. push ax ; Save handle
  1139. push cx
  1140. test cl,GA_DISCARDABLE
  1141. jz short @F
  1142. inc ds:[esi].pga_count ; don't want to discard if discardable
  1143. @@: xor ax,ax ; Try to get a fixed segment.
  1144. mov ebx,ds:[esi].pga_size
  1145. mov cx,ds:[esi].pga_owner
  1146. call gsearch ; AX = segment
  1147. pop cx
  1148. pop bx ; Object handle.
  1149. push eax ; Return from gsearch
  1150. cCall get_arena_pointer32,<bx> ; Get arena header, gsearch may
  1151. ; have moved the global object!
  1152. mov esi,eax ; ESI is old block
  1153. test cl,GA_DISCARDABLE
  1154. jz short @F
  1155. dec ds:[esi].pga_count ; undo lock
  1156. @@:
  1157. pop eax ; EAX is new block
  1158. or eax,eax
  1159. push bx ; Handle
  1160. jz short lock_in_place ; Couldn't get memory.
  1161. mov ebx, ds:[eax].pga_address
  1162. cmp ebx, ds:[esi].pga_address
  1163. jbe short ok_to_move ; Let's not move it up in memory!!
  1164. cCall PreAllocArena
  1165. jz short lock_in_place
  1166. push esi
  1167. mov esi, eax
  1168. xor edx, edx
  1169. call gmarkfree
  1170. pop esi
  1171. jmp short lock_in_place
  1172. ok_to_move:
  1173. mov edx, esi
  1174. mov esi, eax
  1175. mov ebx,ga_next ; This is always an exact fit.
  1176. call gmovebusy ; Wire it on down.
  1177. lock_in_place:
  1178. pop bx ; Handle
  1179. ret
  1180. UnSetKernelDS fs
  1181. cEnd nogen
  1182. ;-----------------------------------------------------------------------;
  1183. ; GlobalUnWire ;
  1184. ; ;
  1185. ; ;
  1186. ; Arguments: ;
  1187. ; ;
  1188. ; Returns: ;
  1189. ; ;
  1190. ; Error Returns: ;
  1191. ; ;
  1192. ; Registers Preserved: ;
  1193. ; ;
  1194. ; Registers Destroyed: ;
  1195. ; ;
  1196. ; Calls: ;
  1197. ; ;
  1198. ; History: ;
  1199. ; ;
  1200. ; Wed Sep 16, 1987 04:28:49p -by- David N. Weise [davidw] ;
  1201. ; Wrote it. ;
  1202. ;-----------------------------------------------------------------------;
  1203. cProc IGlobalUnWire,<PUBLIC,FAR>
  1204. ; parmW handle
  1205. cBegin nogen
  1206. call xhandle
  1207. jz short guw_done
  1208. if 0
  1209. mov bx, ax
  1210. sel_check bx
  1211. SetKernelDS es
  1212. mov es, gdtdsc
  1213. UnSetKernelDS es
  1214. test byte ptr es:[bx+6], 10h
  1215. jz short guw_not_disccode
  1216. test byte ptr es:[bx+5], 8 ; Is it code?
  1217. jz short guw_not_disccode ; nope, no point setting it
  1218. else
  1219. lar ebx, eax
  1220. shr ebx, 8
  1221. test bh, DSC_DISCARDABLE
  1222. jz short guw_not_disccode
  1223. test bl, DSC_CODE_BIT ; Is it code?
  1224. jz short guw_not_disccode ; nope, no point setting it
  1225. endif
  1226. or ds:[esi].pga_flags,GA_DISCCODE
  1227. call glruadd
  1228. guw_not_disccode:
  1229. if KDEBUG
  1230. cmp ch,00h ; Debugging check for count underflow
  1231. jne short unlock1
  1232. push bx ; then the count is wrong.
  1233. push cx
  1234. push dx
  1235. xor cx,cx
  1236. kerror ERR_GMEMUNLOCK,<GlobalUnWire: Object usage count underflow>,cx,bx
  1237. pop dx
  1238. pop cx
  1239. pop bx
  1240. unlock1:
  1241. endif
  1242. call gunlock
  1243. mov ax, 0FFFFh ; TRUE
  1244. jcxz guw_done
  1245. inc ax ; FALSE
  1246. guw_done:
  1247. jmp xhandlex
  1248. cEnd nogen
  1249. ;-----------------------------------------------------------------------;
  1250. ; GlobalCompact ;
  1251. ; ;
  1252. ; Compacts the global arena until a free block of the requested size ;
  1253. ; appears. Contrary to the toolkit it ALWAYS compacts! ;
  1254. ; ;
  1255. ; Arguments: ;
  1256. ; DWORD minimum bytes wanted ;
  1257. ; ;
  1258. ; Returns: ;
  1259. ; ;
  1260. ; Error Returns: ;
  1261. ; ;
  1262. ; Registers Preserved: ;
  1263. ; ;
  1264. ; Registers Destroyed: ;
  1265. ; ;
  1266. ; Calls: ;
  1267. ; ;
  1268. ; History: ;
  1269. ; ;
  1270. ; Wed 26-Apr-1989 15:33:18 -by- David N. Weise [davidw] ;
  1271. ; Added the zero'ing of ES on exit. ;
  1272. ; ;
  1273. ; Wed Dec 03, 1986 01:09:02p -by- David N. Weise [davidw] ;
  1274. ; Added this nifty comment block. ;
  1275. ;-----------------------------------------------------------------------;
  1276. cProc GlobalCompact,<PUBLIC,FAR>
  1277. parmD minBytes
  1278. localD DPMIbytes
  1279. cBegin
  1280. GENTER32 ; About to modify memory arena
  1281. CheckHeap GlobalCompact
  1282. call GetDPMIFreeSpace ; EAX = largest free DPMI block
  1283. and ax, GA_MASK_BYTES
  1284. mov ebx, eax
  1285. clc
  1286. call galign ; align size
  1287. mov eax, edx ; EAX = aligned DPMI block
  1288. mov DPMIbytes, eax
  1289. cmp eax, minBytes ; Q: Enough to satisfy request?
  1290. jb SHORT GCReallyCompact ; N: Really compact heap
  1291. cmp eax, 512*1024 ; Q: Less than 1/2 Mb of DPMI mem?
  1292. jnb SHORT GCWorked
  1293. GCReallyCompact:
  1294. if KDEBUG
  1295. push ax
  1296. push bx
  1297. mov ax, seg_minBytes
  1298. mov bx, off_minBytes
  1299. krDebugOut DEB_WARN, "%SS2 GlobalCompact(#ax#BX), discarding segments"
  1300. pop bx
  1301. pop ax
  1302. endif
  1303. mov ax,-1
  1304. lea bx,minBytes
  1305. call gbtop
  1306. assumes es, nothing
  1307. clc ; galign should be called with CF = 0
  1308. call galign
  1309. call gavail ; Returns paragraphs in DX:AX
  1310. cmp eax, DPMIbytes ; Return max of gavail or DMPI free
  1311. jae SHORT GCWorked ; space
  1312. mov eax, DPMIbytes
  1313. GCWorked:
  1314. mov edx, eax
  1315. shr edx, 16
  1316. mov cx, ax
  1317. or cx, dx
  1318. GLEAVE32
  1319. pushad
  1320. call ShrinkHeap
  1321. popad
  1322. cEnd
  1323. ;-----------------------------------------------------------------------;
  1324. ; GlobalNotify ;
  1325. ; ;
  1326. ; This sets a procedure to call when a discardable segment belonging ;
  1327. ; to this task gets discarded. The discardable object must have been ;
  1328. ; allocated with the GMEM_DISCARDABLE bit set. ;
  1329. ; ;
  1330. ; Arguments: ;
  1331. ; parmD NotifyProc ;
  1332. ; ;
  1333. ; Returns: ;
  1334. ; nothing ;
  1335. ; ;
  1336. ; Error Returns: ;
  1337. ; ;
  1338. ; Registers Preserved: ;
  1339. ; AX,CX,DX,DI,SI,DS ;
  1340. ; ;
  1341. ; Registers Destroyed: ;
  1342. ; BX,ES ;
  1343. ; ;
  1344. ; Calls: ;
  1345. ; nothing ;
  1346. ; ;
  1347. ; History: ;
  1348. ; ;
  1349. ; Tue Jun 23, 1987 10:16:32p -by- David N. Weise [davidw] ;
  1350. ; Wrote it. ;
  1351. ;-----------------------------------------------------------------------;
  1352. cProc IGlobalNotify,<PUBLIC,FAR>
  1353. parmD NotifyProc
  1354. cBegin
  1355. push ds
  1356. les bx,NotifyProc ; verify pointer
  1357. SetKernelDS
  1358. mov ds,curTDB
  1359. UnSetKernelDS
  1360. mov word ptr ds:[TDB_GNotifyProc][2],es
  1361. mov word ptr ds:[TDB_GNotifyProc][0],bx
  1362. pop ds
  1363. cEnd
  1364. cProc GlobalMasterHandle,<PUBLIC,FAR>
  1365. cBegin nogen
  1366. push ds
  1367. SetKernelDS
  1368. mov ax,hGlobalHeap
  1369. mov dx,pGlobalHeap
  1370. UnSetKernelDS
  1371. pop ds
  1372. ret
  1373. cEnd nogen
  1374. ;-----------------------------------------------------------------------;
  1375. ; GetTaskDS ;
  1376. ; ;
  1377. ; Gets the segment of the current task's DS. ;
  1378. ; ;
  1379. ; Arguments: ;
  1380. ; none ;
  1381. ; ;
  1382. ; Returns: ;
  1383. ; AX = selector. ;
  1384. ; DX = selector. ;
  1385. ; ;
  1386. ; Error Returns: ;
  1387. ; ;
  1388. ; Registers Preserved: ;
  1389. ; ;
  1390. ; Registers Destroyed: ;
  1391. ; ;
  1392. ; Calls: ;
  1393. ; nothing ;
  1394. ; ;
  1395. ; History: ;
  1396. ; ;
  1397. ; Thu Jun 25, 1987 10:52:10p -by- David N. Weise [davidw] ;
  1398. ; Wrote it. ;
  1399. ;-----------------------------------------------------------------------;
  1400. cProc GetTaskDS,<PUBLIC,FAR>
  1401. cBegin nogen
  1402. push ds
  1403. SetKernelDS
  1404. mov ds,curTDB
  1405. UnsetKernelDS
  1406. mov ax,ds:[TDB_Module]
  1407. mov dx,ax
  1408. pop ds
  1409. ret
  1410. cEnd nogen
  1411. assumes ds,nothing
  1412. assumes es,nothing
  1413. cProc IGlobalLRUOldest,<PUBLIC,FAR>
  1414. ; parmW handle
  1415. cBegin nogen
  1416. call xhandle ; Call ghandle with handle in DX
  1417. jz short xhandlex2
  1418. call glrubot
  1419. xhandlex2:
  1420. jmp xhandlex
  1421. cEnd nogen
  1422. cProc IGlobalLRUNewest,<PUBLIC,FAR>
  1423. ; parmW handle
  1424. cBegin nogen
  1425. call xhandle ; Call ghandle with handle in DX
  1426. jz short xhandlex2
  1427. call glrutop
  1428. jmp xhandlex
  1429. cEnd nogen
  1430. ;-----------------------------------------------------------------------;
  1431. ; SwitchStackTo ;
  1432. ; ;
  1433. ; Switched to the given stack, and establishes the BP chain. It also ;
  1434. ; copies the last stack arguments from the old stack to the new stack. ;
  1435. ; ;
  1436. ; Arguments: ;
  1437. ; parmW new_ss ;
  1438. ; parmW new_sp ;
  1439. ; parmW stack_top ;
  1440. ; ;
  1441. ; Returns: ;
  1442. ; A new stack! ;
  1443. ; ;
  1444. ; Error Returns: ;
  1445. ; ;
  1446. ; Registers Preserved: ;
  1447. ; DI,SI,DS ;
  1448. ; ;
  1449. ; Registers Destroyed: ;
  1450. ; AX,BX,CX,DX,ES ;
  1451. ; ;
  1452. ; Calls: ;
  1453. ; nothing ;
  1454. ; ;
  1455. ; History: ;
  1456. ; ;
  1457. ; Tue Sep 22, 1987 08:42:05p -by- David N. Weise [davidw] ;
  1458. ; Wrote it. ;
  1459. ;-----------------------------------------------------------------------;
  1460. assumes ds,nothing
  1461. assumes es,nothing
  1462. cProcVDO SwitchStackTo,<PUBLIC,FAR>
  1463. ; parmW new_ss
  1464. ; parmW new_sp
  1465. ; parmW stack_top
  1466. cBegin nogen
  1467. SetKernelDS es
  1468. FCLI
  1469. mov GSS_SI,si
  1470. mov GSS_DS,ds
  1471. pop word ptr GSS_RET[0] ; get the return address
  1472. pop word ptr GSS_RET[2]
  1473. assumes es, nothing
  1474. pop ax ; stack_top
  1475. pop bx ; new_sp
  1476. pop dx ; new_ss
  1477. mov si,bp ; Calculate # of parameters on stack.
  1478. dec si ; remove DS
  1479. dec si
  1480. mov cx,si
  1481. sub cx,sp
  1482. shr cx,1
  1483. push bp ; save BP
  1484. smov es,ss
  1485. mov ds,dx ; new_ss
  1486. mov ds:[2],sp
  1487. mov ds:[4],ss
  1488. mov ds:[pStackTop],ax
  1489. mov ds:[pStackMin],bx
  1490. mov ds:[pStackBot],bx
  1491. ; switch stacks
  1492. mov ss,dx
  1493. mov sp,bx
  1494. mov bp,bx
  1495. xor ax,ax
  1496. push ax ; null terminate bp chain
  1497. jcxz no_args
  1498. copy_args:
  1499. dec si
  1500. dec si
  1501. push es:[si]
  1502. loop copy_args
  1503. no_args:
  1504. SetKernelDS
  1505. mov es,curTDB
  1506. mov es:[TDB_taskSS],ss
  1507. mov es:[TDB_taskSP],sp
  1508. push GSS_RET.sel
  1509. push GSS_RET.off ; get the return address
  1510. mov si,GSS_SI
  1511. mov ds,GSS_DS
  1512. FSTI
  1513. ret
  1514. cEnd nogen
  1515. ;-----------------------------------------------------------------------;
  1516. ; SwitchStackBack ;
  1517. ; ;
  1518. ; Switches to the stack stored at SS:[2], and restores BP. Preserves ;
  1519. ; AX and DX so that results can be passed back from the last call. ;
  1520. ; ;
  1521. ; Arguments: ;
  1522. ; none ;
  1523. ; ;
  1524. ; Returns: ;
  1525. ; The old stack! ;
  1526. ; ;
  1527. ; Error Returns: ;
  1528. ; ;
  1529. ; Registers Preserved: ;
  1530. ; AX,DX,DI,SI,DS ;
  1531. ; ;
  1532. ; Registers Destroyed: ;
  1533. ; BX,CX,ES ;
  1534. ; ;
  1535. ; Calls: ;
  1536. ; nothing ;
  1537. ; ;
  1538. ; History: ;
  1539. ; ;
  1540. ; Tue Sep 22, 1987 09:56:32p -by- David N. Weise [davidw] ;
  1541. ; Wrote it. ;
  1542. ;-----------------------------------------------------------------------;
  1543. assumes ds,nothing
  1544. assumes es,nothing
  1545. cProc SwitchStackBack,<PUBLIC,FAR>
  1546. cBegin nogen
  1547. push ds
  1548. SetKernelDS
  1549. FCLI
  1550. pop GSS_DS
  1551. pop GSS_RET.off ; get the return address
  1552. pop GSS_RET.sel
  1553. xor bx,bx
  1554. xor cx,cx
  1555. xchg bx,ss:[4]
  1556. xchg cx,ss:[2]
  1557. mov ss,bx
  1558. mov sp,cx
  1559. mov es,curTDB
  1560. mov es:[TDB_taskSS],ss
  1561. mov es:[TDB_taskSP],sp
  1562. pop bp
  1563. push GSS_RET.sel
  1564. push GSS_RET.off ; get the return address
  1565. mov ds,GSS_DS
  1566. UnSetKernelDS
  1567. FSTI
  1568. ret
  1569. cEnd nogen
  1570. ;-----------------------------------------------------------------------;
  1571. ; GetFreeMemInfo ;
  1572. ; ;
  1573. ; Get free and unlocked pages in paging system ;
  1574. ; ;
  1575. ; Arguments: ;
  1576. ; none ;
  1577. ; ;
  1578. ; Returns: ;
  1579. ; DX Free pages ;
  1580. ; AX Unlocked pages ;
  1581. ; ;
  1582. ; Error Returns: ;
  1583. ; ;
  1584. ; Registers Preserved: ;
  1585. ; DI,SI,DS ;
  1586. ; ;
  1587. ; Registers Destroyed: ;
  1588. ; ES ;
  1589. ; ;
  1590. ; Calls: ;
  1591. ; nothing ;
  1592. ; ;
  1593. ; History: ;
  1594. ; ;
  1595. ;-----------------------------------------------------------------------;
  1596. assumes ds, nothing
  1597. assumes es, nothing
  1598. cProc GetFreeMemInfo,<PUBLIC,FAR>,<di>
  1599. localV mem_info,30h
  1600. cBegin
  1601. mov ax, -1
  1602. mov dx, ax
  1603. SetKernelDS es
  1604. test byte ptr WinFlags[1], WF1_PAGING
  1605. jz short gfmi_no_info
  1606. lea di, mem_info
  1607. smov es, ss
  1608. UnSetKernelDS es
  1609. DPMICALL 0500h ; Get Free Memory Information
  1610. jc short gfmi_no_info
  1611. mov ax, es:[di][10h]
  1612. mov dx, es:[di][14h]
  1613. gfmi_no_info:
  1614. cEnd
  1615. ;-----------------------------------------------------------------------;
  1616. ; GetFreeSpace ;
  1617. ; ;
  1618. ; Calculates the current amount of free space ;
  1619. ; ;
  1620. ; Arguments: ;
  1621. ; flags - ignored for non-EMS system ;
  1622. ; ;
  1623. ; Returns: ;
  1624. ; DX:AX Free space in bytes ;
  1625. ; ;
  1626. ; Error Returns: ;
  1627. ; ;
  1628. ; Registers Preserved: ;
  1629. ; DI,SI,DS ;
  1630. ; ;
  1631. ; Registers Destroyed: ;
  1632. ; BX,CX,ES ;
  1633. ; ;
  1634. ; Calls: ;
  1635. ; nothing ;
  1636. ; ;
  1637. ; History: ;
  1638. ; ;
  1639. ; Wed 26-Apr-1989 15:33:18 -by- David N. Weise [davidw] ;
  1640. ; Added the zero'ing of ES on exit. ;
  1641. ; ;
  1642. ;-----------------------------------------------------------------------;
  1643. assumes ds, nothing
  1644. assumes es, nothing
  1645. cProc IGetFreeSpace,<PUBLIC,FAR>
  1646. parmW flags
  1647. cBegin
  1648. GENTER32
  1649. call GetDPMIFreeSpace ; EDX = Free DPMI heap space
  1650. mov esi, [di].phi_first
  1651. gfs_loop:
  1652. mov esi, ds:[esi].pga_next
  1653. cmp ds:[esi].pga_sig, GA_ENDSIG
  1654. je short gfs_last ; End of heap
  1655. mov ax, ds:[esi].pga_owner
  1656. cmp ax, GA_NOT_THERE
  1657. je short gfs_loop ; Nothing there
  1658. or ax, ax ; Free?
  1659. jz short gfs_include ; yes, include
  1660. test flags, 2 ; Ignore discardable?
  1661. jnz short gfs_loop ; yes.
  1662. mov bx, ds:[esi].pga_handle
  1663. test bl, GA_FIXED
  1664. jnz short gfs_loop ; Fixed block if odd
  1665. cmp ds:[esi].pga_sig, 0
  1666. jne short gfs_loop ; skip if locked
  1667. lar ebx, ebx
  1668. shr ebx, 8
  1669. test bh, DSC_DISCARDABLE ; include if discardable
  1670. jz short gfs_loop
  1671. gfs_include:
  1672. add edx, ds:[esi].pga_size
  1673. jmps gfs_loop
  1674. gfs_last:
  1675. test flags, 2 ; Ignoring discardable?
  1676. jnz short @F ; yes, then ignore fence
  1677. sub edx, [di].gi_reserve ; Subtract out that above fence
  1678. @@:
  1679. sub edx, 10000h ; Lose 64k of it for fun
  1680. jns short gfs_positive ; Return zero if we
  1681. xor edx, edx ; went negative!
  1682. gfs_positive:
  1683. ;
  1684. ; Now check to see if this app has troubles if the value gets too huge.
  1685. ; 61a8000h is 100MB
  1686. ;
  1687. WOW_FREE_SPACE_CAP equ 61a8000h
  1688. push edx
  1689. cCall MyGetAppWOWCompatFlags ; check if we need to cap it
  1690. test dx, WOWCF_LIMIT_MEM_FREE_SPACE SHR 16
  1691. pop edx
  1692. jz short @f
  1693. cmp edx, WOW_FREE_SPACE_CAP
  1694. jb short @f
  1695. mov edx, WOW_FREE_SPACE_CAP
  1696. @@:
  1697. mov eax, edx ; Return in DX:AX
  1698. shr edx, 16
  1699. GLEAVE32
  1700. cEnd
  1701. ;-----------------------------------------------------------------------;
  1702. ; GetDPMIFreeSpace ;
  1703. ; ;
  1704. ; Calculates the current amount of DPMI free space ;
  1705. ; ;
  1706. ; Arguments: ;
  1707. ; None ;
  1708. ; ;
  1709. ; Returns: ;
  1710. ; EAX = Size of largest free block in bytes ;
  1711. ; EDX = Free DPMI space in bytes ;
  1712. ; DI = 0 ;
  1713. ; ;
  1714. ; Error Returns: ;
  1715. ; ;
  1716. ; Registers Preserved: ;
  1717. ; DI,SI,DS ;
  1718. ; ;
  1719. ; Registers Destroyed: ;
  1720. ; BX,CX,ES ;
  1721. ; ;
  1722. ; Calls: ;
  1723. ; nothing ;
  1724. ; ;
  1725. ; History: ;
  1726. ; ;
  1727. ;-----------------------------------------------------------------------;
  1728. assumes ds, nothing
  1729. assumes es, nothing
  1730. ifdef WOW
  1731. cProc GetDPMIFreeSpace,<PUBLIC,NEAR>,<edi,esi,cx>
  1732. cBegin
  1733. push bp
  1734. mov cx, sp
  1735. and cx, 3 ;prepare to align on dword
  1736. add cx, SIZE GMEMSTATUS_block ;length to adjust sp
  1737. sub sp, cx
  1738. mov bp, sp ;base pointer to structure
  1739. mov dwLength[bp], SIZE GMEMSTATUS_block
  1740. cCall GlobalMemoryStatus,<ss,bp> ;Call NT To get Memory Info
  1741. mov edx,dwAvailPhys[bp] ; if (dwAvailVirtual < dwAvailPhys +dwAvailPagefile)
  1742. add edx,dwAvailPageFile[bp] ; return(dwAvailVirtual
  1743. cmp dwAvailVirtual[bp],edx ; else
  1744. ja @f ; return(dwAvailPhys +dwAvailPagefile)
  1745. mov edx,dwAvailVirtual[bp]
  1746. @@:
  1747. mov eax,dwAvailPhys[bp] ; Not entirely accurate equivalent
  1748. ; of Windows, should be OK
  1749. add sp, cx ;restore stack pointer
  1750. pop bp
  1751. else; NOT WOW
  1752. cProc GetDPMIFreeSpace,<PUBLIC,NEAR>
  1753. localV mem_info,30h
  1754. cBegin
  1755. xor edx, edx ; In case of DPMI failure
  1756. lea di, mem_info
  1757. smov es, ss
  1758. DPMICALL 0500h ; Get Free Memory Information
  1759. jc short xoredxedx
  1760. mov edx, dword ptr mem_info[14h] ; Number of free pages (if not paging)
  1761. mov eax, dword ptr mem_info[20h] ; Paging file size
  1762. inc eax
  1763. cmp eax, 1 ; 0 or -1?
  1764. jbe short not_paging ; yes, no paging
  1765. lea edx, [eax-1] ; no, paging file size in edx
  1766. ;
  1767. ; Calculation is:
  1768. ; (Paging file size + Total physical pages)
  1769. ; - (Total linear space - Free linear space)
  1770. ;
  1771. ; Actually, there are two limits to total swap area. (Since Win386
  1772. ; isn't a planned product, it first allocates data structures for
  1773. ; linear memory, then discovers how big the page file is.)
  1774. ; First, find out how many pages we have - this is the sum of
  1775. ; physical pages owned by DPMI, and pages in the disk swap file.
  1776. ; Next, find out how many pages are allowed for in the linear
  1777. ; address data structure. The lesser of these two values is
  1778. ; the limit. Next, subtract the already allocated pages. This
  1779. ; is found as the difference between total linear, and free linear
  1780. ; space. The final result is close to the amount of allocatable
  1781. ; virtual memory.
  1782. add edx, dword ptr mem_info[18h] ; Total physical pages
  1783. cmp edx, dword ptr mem_info[0ch] ; Allocatable linear memory
  1784. jl short @F
  1785. mov edx, dword ptr mem_info[0ch] ; take the smaller
  1786. @@:
  1787. add edx, dword ptr mem_info[1Ch] ; Free linear space
  1788. sub edx, dword ptr mem_info[0Ch] ; Total linear space
  1789. not_paging:
  1790. mov eax, dword ptr mem_info ; size of largest free block
  1791. shl edx, 12 ; Convert to bytes
  1792. jns short no_info ; Went negative?
  1793. xor edx, edx
  1794. endif: WOW
  1795. no_info:
  1796. ;
  1797. ; !!! HACK ALERT !!!
  1798. ; We don't actually want to grab all the memory from DPMI, because then
  1799. ; we won't be able to allocate DPMI memory for arena tables, if we
  1800. ; need them, and WIN386 won't be able to grow the LDT.
  1801. ;
  1802. sub edx,10000h
  1803. ja @F
  1804. xoredxedx:
  1805. xor edx,edx
  1806. @@:
  1807. cmp eax,edx
  1808. jb @F
  1809. mov eax,edx
  1810. @@:
  1811. xor di, di
  1812. cEnd
  1813. ;-----------------------------------------------------------------------;
  1814. ; GlobalDOSAlloc
  1815. ;
  1816. ; Allocates memory that is accessible by DOS.
  1817. ;
  1818. ; Entry:
  1819. ; parmD nbytes number of bytes to alloc
  1820. ;
  1821. ; Returns:
  1822. ; AX = memory handle
  1823. ; DX = DOS segment paragraph address
  1824. ;
  1825. ; History:
  1826. ; Tue 23-May-1989 11:30:57 -by- David N. Weise [davidw]
  1827. ; Wrote it!
  1828. ;-----------------------------------------------------------------------;
  1829. assumes ds,nothing
  1830. assumes es,nothing
  1831. cProc GlobalDOSAlloc,<PUBLIC,FAR>,<di,si>
  1832. parmD nbytes
  1833. cBegin
  1834. mov ax,GA_ALLOC_DOS shl 8
  1835. cCall IGlobalAlloc,<ax,nbytes>
  1836. xor dx, dx ; In case of error return
  1837. or ax, ax
  1838. jz short gda_exit
  1839. push ax
  1840. cCall get_physical_address,<ax>
  1841. REPT 4
  1842. shr dx, 1
  1843. rcr ax, 1
  1844. ENDM
  1845. mov dx, ax
  1846. pop ax
  1847. gda_exit:
  1848. cEnd
  1849. ;-----------------------------------------------------------------------;
  1850. ; GlobalDOSFree
  1851. ;
  1852. ; Frees memory allocated by GlobalDOSAlloc.
  1853. ;
  1854. ; Entry:
  1855. ; parmW handle
  1856. ;
  1857. ; Returns:
  1858. ;
  1859. ; Registers Destroyed:
  1860. ;
  1861. ; History:
  1862. ; Tue 23-May-1989 17:48:03 -by- David N. Weise [davidw]
  1863. ; Wrote it!
  1864. ;-----------------------------------------------------------------------;
  1865. assumes ds,nothing
  1866. assumes es,nothing
  1867. cProc GlobalDOSFree,<PUBLIC,FAR>,<di,si>
  1868. parmW handle
  1869. cBegin
  1870. cCall IGlobalFree,<handle>
  1871. cEnd
  1872. ;-----------------------------------------------------------------------;
  1873. ; GlobalPageLock
  1874. ;
  1875. ; Page locks the memory associated with the Handle.
  1876. ;
  1877. ; Entry:
  1878. ; parmW handle
  1879. ;
  1880. ; Returns:
  1881. ; AX = new lock count
  1882. ;
  1883. ; History:
  1884. ; Wed 31-May-1989 22:14:21 -by- David N. Weise [davidw]
  1885. ; Wrote it!
  1886. ;-----------------------------------------------------------------------;
  1887. assumes ds,nothing
  1888. assumes es,nothing
  1889. cProc IGlobalPageLock,<PUBLIC,FAR>
  1890. ; parmW handle
  1891. cBegin nogen
  1892. call xhandle
  1893. or ax,ax
  1894. jz short gpl_fail ; Ignore invalid or discarded objects
  1895. cmp [esi].pga_pglock, 0FFh ; About to overflow?
  1896. je short gpl_over
  1897. push dx
  1898. call gwire ; Move it LOW!
  1899. pop bx
  1900. ifndef WOW
  1901. DPMICALL 4 ; Page Lock it
  1902. jc short gpl_fail
  1903. endif
  1904. inc [esi].pga_count
  1905. inc [esi].pga_pglock
  1906. movzx ax, [esi].pga_pglock
  1907. jmp xhandlex
  1908. gpl_over:
  1909. if KDEBUG
  1910. push bx
  1911. push cx
  1912. push dx
  1913. xor cx,cx
  1914. kerror ERR_GMEMLOCK,<GlobalPageLock: Lock count overflow>,cx,bx
  1915. pop dx
  1916. pop cx
  1917. pop bx
  1918. endif
  1919. gpl_fail:
  1920. xor ax,ax
  1921. jmp xhandlex
  1922. cEnd nogen
  1923. ;-----------------------------------------------------------------------;
  1924. ; GlobalPageUnlock
  1925. ;
  1926. ; Page unlocks the memory associated with the Handle.
  1927. ;
  1928. ; Entry:
  1929. ; parmW handle
  1930. ;
  1931. ; Returns:
  1932. ; AX = new lock count
  1933. ;
  1934. ; History:
  1935. ; Wed 31-May-1989 22:14:21 -by- David N. Weise [davidw]
  1936. ; Wrote it!
  1937. ;-----------------------------------------------------------------------;
  1938. assumes ds,nothing
  1939. assumes es,nothing
  1940. cProc IGlobalPageUnlock,<PUBLIC,FAR>
  1941. ; parmW handle
  1942. cBegin nogen
  1943. call xhandle
  1944. or ax,ax
  1945. jz short gpu_fail ; Ignore invalid or discarded objects
  1946. cmp [esi].pga_pglock, 0 ; About to underflow?
  1947. je short gpu_under
  1948. mov bx, dx
  1949. ifndef WOW
  1950. DPMICALL 5
  1951. jc short gpu_fail
  1952. endif
  1953. dec [esi].pga_count
  1954. dec [esi].pga_pglock
  1955. movzx ax, [esi].pga_pglock
  1956. jmp xhandlex
  1957. gpu_under:
  1958. if KDEBUG
  1959. xor ax,ax
  1960. push bx
  1961. push cx
  1962. push dx
  1963. xor cx,cx
  1964. kerror ERR_GMEMUNLOCK,<GlobalPageUnlock: Lock count underflow>,cx,bx
  1965. pop dx
  1966. pop cx
  1967. pop bx
  1968. endif
  1969. gpu_fail:
  1970. xor ax, ax
  1971. jmp xhandlex
  1972. cEnd nogen
  1973. ;
  1974. ; Win95 implements GlobalSmartPageLock and GlobalSmartPageUnlock
  1975. ; here in 3ginterf.asm. These routines will page-lock the given
  1976. ; global memory object only if the system is paging via DOS (as
  1977. ; opposed to 32-bit Disk Access), otherwise the memory is locked
  1978. ; in linear memory using GlobalFix. Callers use these routines
  1979. ; for memory which may be accessed while handling an Int 21, to
  1980. ; prevent re-entering DOS. Since we never page via Int 21, we
  1981. ; simply export GlobalFix as GlobalSmartPageLock and GlobalUnfix
  1982. ; as GlobalSmartPageUnlock.
  1983. ;
  1984. ifdef WOW
  1985. ;--------------------------------------------------------------------------;
  1986. ;
  1987. ; Similar to GlobalFlags
  1988. ;
  1989. ;--------------------------------------------------------------------------;
  1990. cProc SetCursorIconFlag,<PUBLIC,FAR>,<ds,es,esi>
  1991. parmW handle
  1992. parmW fSet
  1993. cBegin
  1994. SetKernelDS es
  1995. mov ds, pGlobalHeap
  1996. UnSetKernelDS
  1997. cCall get_arena_pointer32,<handle> ; get the owner
  1998. or eax,eax
  1999. jz sf_error
  2000. mov esi,eax
  2001. mov ax,fSet
  2002. or ax,ax
  2003. jz sf_unset
  2004. or ds:[esi].pga_flags, GAH_CURSORICON ;cursor, icon, or accelerator
  2005. jmps sf_error
  2006. sf_unset:
  2007. and ds:[esi].pga_flags, NOT GAH_CURSORICON
  2008. sf_error:
  2009. xor ax,ax
  2010. cEnd
  2011. ;--------------------------------------------------------------------------;
  2012. ;
  2013. ; Stamp the 01h in globalarena for DDE handles. This is GAH_PHANTOM flag
  2014. ; which is not used any longer.
  2015. ;
  2016. ;--------------------------------------------------------------------------;
  2017. cProc SetDdeHandleFlag,<PUBLIC,FAR>,<ds,es,esi>
  2018. parmW handle
  2019. parmW fSet
  2020. cBegin
  2021. SetKernelDS es
  2022. mov ds, pGlobalHeap
  2023. UnSetKernelDS
  2024. cCall get_arena_pointer32,<handle> ; get the owner
  2025. or eax,eax
  2026. jz sd_error
  2027. mov esi,eax
  2028. mov ax,fSet
  2029. or ax,ax
  2030. jz sd_unset
  2031. or ds:[esi].pga_flags, GAH_WOWDDEFREEHANDLE
  2032. jmps sd_error
  2033. sd_unset:
  2034. and ds:[esi].pga_flags, NOT GAH_WOWDDEFREEHANDLE
  2035. sd_error:
  2036. xor ax,ax
  2037. cEnd
  2038. endif
  2039. sEnd CODE
  2040. end