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.

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