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.

1386 lines
25 KiB

  1. ;=======================================================
  2. ;
  3. ; Macros stolen from cmacros.inc (so we don't have to include it all)
  4. ;
  5. .286p
  6. externNP macro n
  7. irp x,<n>
  8. extrn x:near
  9. endm
  10. endm
  11. externFP macro n
  12. irp x,<n>
  13. extrn x:far
  14. endm
  15. endm
  16. externW macro w
  17. irp x,<w>
  18. extrn x:word
  19. endm
  20. endm
  21. assumes macro s,ln
  22. assume s:_&ln
  23. endm
  24. createSeg macro n,ln,a,co,cl,grp
  25. n segment a co '&cl'
  26. n ends
  27. endm
  28. sBegin macro seg
  29. assume cs:_&seg
  30. _&seg segment
  31. endm
  32. sEnd macro seg
  33. _&seg ends
  34. assume cs:nothing
  35. endm
  36. errnz macro x ;;display error if expression is <>0
  37. if2
  38. if x ;;if expression is non-zero,
  39. errnz1 <x>,%(x)
  40. endif
  41. endif
  42. endm
  43. errnz1 macro x1,x2
  44. = *errnz* x1 = x2
  45. .err
  46. endm
  47. errn$ macro l,x ;;error if <$-label1 (exp2)> <>0
  48. errnz <offset $ - offset l x>
  49. endm
  50. createSeg _DATA,DATA,WORD,PUBLIC,DATA
  51. ;=======================================================
  52. ;
  53. ; Error API definitions
  54. ;
  55. ExternFP <HandleParamError>
  56. ; error codes
  57. include logerror.inc
  58. ;================================================================
  59. ; Variable and temporary initialization
  60. VLseg equ <> ; Holds current segment name
  61. VLopen = 0
  62. VLerrnotinvoked = 0
  63. ifndef VLnogenpall
  64. VLnogenpall = 0
  65. endif
  66. VLnogen = 0
  67. VLnogenparm = 0
  68. VLsavees = 0
  69. VLsavebx = 0
  70. ;if1
  71. if 1
  72. ;================================================================
  73. ; Utility macros
  74. ;---------------------------------------------------------------------------
  75. ;
  76. ; lodsw cs:[si]
  77. ;
  78. cslodsw macro
  79. db 2eh ;; CS override
  80. lodsw
  81. endm
  82. ;---------------------------------------------------------------------------
  83. ;
  84. ; lodsb cs:[si]
  85. ;
  86. cslodsb macro
  87. db 2eh ;; CS override
  88. lodsb
  89. endm
  90. SkipTwoBytes macro
  91. db 0A9h ;; Opcode for CMP AX,(immediate word)
  92. endm
  93. ;---------------------------------------------------------------------------
  94. ;
  95. ; Define a as the concatenation of b & c
  96. ;
  97. concat macro a,b,c,d,e,f
  98. a equ <b&c&d&e&f>
  99. endm
  100. ;---------------------------------------------------------------------------
  101. ;
  102. ; Assign a to b.
  103. ;
  104. equate macro a,b
  105. a = b
  106. endm
  107. ;
  108. ; Print a message
  109. ;
  110. _print macro a,b,c
  111. if2
  112. %out a&b&c
  113. endif
  114. endm
  115. ;===============================================================
  116. ;---------------------------------------------------------------------------
  117. ;
  118. ; _gensub LABEL
  119. ;
  120. ; Causes per-segment subroutine code associated with type LABEL
  121. ; to be generated, by setting the genLABEL&lseg flag.
  122. ;
  123. _gensub2 macro l,s
  124. gen&l&s = 1
  125. endm
  126. _gensub macro l
  127. _gensub2 <l>,%VLseg
  128. endm
  129. ;---------------------------------------------------------------------------
  130. ; _SwitchSeg
  131. ;
  132. ; Switches current segment to seg, creating the segment if needed.
  133. ;
  134. _SwitchSeg macro seg,oldseg
  135. ifdifi <&seg>,<oldseg>
  136. ifnb <oldseg>
  137. sEnd oldseg
  138. endif
  139. concat <VLseg>,seg,
  140. ;createSeg _&seg,seg,BYTE,PUBLIC,CODE
  141. createSeg _&seg,seg,WORD,PUBLIC,CODE
  142. sBegin seg
  143. assumes CS,seg
  144. endif
  145. endm
  146. ;---------------------------------------------------------------------------
  147. ; API
  148. ;
  149. API macro rettype,name,seg,optlist
  150. if VLopen
  151. APIEND
  152. endif
  153. VLname equ <name>
  154. VLcbparms = 0
  155. VLcbskip = 0
  156. VLerrnotinvoked= 1
  157. VLopen = 1
  158. VLnogen = 0
  159. VLnogenparm = 0
  160. VLasm = 0
  161. VLfunnyframe = 0
  162. VLnodata = 0
  163. VLcargs = 0
  164. VLplist equ <>
  165. VLATMframe = 0 ; special entry/exit code sequence for ATM's patching
  166. VLATMfrmds = 0 ; ATM entry/exit code: mov ax,_DATA at beginning.
  167. VLsavees = 0
  168. VLsavebx = 0
  169. _SwitchSeg seg,%VLseg
  170. irp opt,<optlist>
  171. ifidni <opt>,<NOGEN>
  172. VLnogen = 1
  173. endif
  174. ifidni <opt>,<VOID>
  175. VLnogen = 1
  176. endif
  177. ifidni <opt>,<ASM>
  178. VLasm = 1
  179. endif
  180. ifndef WOW
  181. ; don't need that bp and ds stuff
  182. ifidni <opt>,<ATMFRAME>
  183. VLATMframe = 1
  184. endif
  185. ifidni <opt>,<ATMFRAMEDS>
  186. VLATMfrmds = 1
  187. VLATMframe = 1
  188. endif
  189. endif
  190. ifidni <opt>,<FUNNYFRAME>
  191. VLfunnyframe = 1
  192. endif
  193. ifidni <opt>,<NODATA>
  194. VLnodata = 1
  195. endif
  196. ifidni <opt>,<DEBUGONLY>
  197. ifndef DEBUG
  198. VLnogen = 1
  199. endif
  200. endif
  201. ifidni <opt>,<C>
  202. VLcargs = 1
  203. endif
  204. ifidni <opt>,<SAVEES>
  205. VLsavees = 2 ; sizeof(ES)
  206. endif
  207. ifidni <opt>,<SAVEBX>
  208. VLsavebx = 2 ; sizeof(BX)
  209. endif
  210. endm
  211. concat <VLsegoffset>,<seg>,<offset>
  212. concat <VLnameerror>,<name>,<_error>
  213. concat <VLnamecbparms>,<name>,<cbparms>
  214. if1
  215. equate %VLnamecbparms, %VLcbparms
  216. else
  217. equate %VLnamecbparms, %VLnamecbparms
  218. endif
  219. ife VLnogen
  220. ife VLcargs
  221. concat <VLiname>,<I>,<name>
  222. ExternNP I&name
  223. public name
  224. name:
  225. else
  226. concat <VLiname>,<_I>,<name>
  227. ExternNP _I&name
  228. public _&name
  229. _&name:
  230. endif
  231. VLframe = 0 ; no frame set up yet.
  232. endif ; VLnogen
  233. endm ;; VL
  234. ;---------------------------------------------------------------------------
  235. ; APIERR
  236. ;
  237. ; Optionally used after parameter decls to begin error handling code
  238. ;
  239. APIERR macro opts
  240. ife VLnogen
  241. ife VLframe
  242. _print <Nothing to validate for >,%VLiname
  243. else
  244. pop dx ; pop off error handler address
  245. pop bp ; restore BP
  246. if VLATMframe
  247. dec bp ; fix BP back up
  248. endif
  249. if VLsavees
  250. pop es
  251. endif
  252. if VLsavebx
  253. pop bx
  254. endif
  255. endif
  256. jmp VLiname ; jmp to internal routine.
  257. equate %VLnamecbparms, %VLcbparms
  258. VLnameerror:
  259. VLerrnotinvoked = 0
  260. endif ; VLnogen
  261. endm ;; APIERR
  262. ;---------------------------------------------------------------------------
  263. ; APIEND
  264. ;
  265. ; Used after APIERR to terminate error handling code.
  266. ;
  267. APIEND macro
  268. _PurgeParms %VLplist
  269. ife VLnogen
  270. if VLerrnotinvoked
  271. APIERR
  272. endif
  273. if VLsavees
  274. pop es
  275. endif
  276. if VLsavebx
  277. pop bx
  278. endif
  279. ife VLcargs
  280. retf VLcbparms
  281. else
  282. retf
  283. endif
  284. VLopen = 0
  285. endif ; VLnogen
  286. endm ;; APIEND
  287. ;---------------------------------------------------------------------------
  288. ;
  289. ; _FlsFrame - Generate frame code
  290. ;
  291. _FlsFrame macro
  292. ife VLframe
  293. if VLATMfrmds
  294. mov ax,_DATA
  295. endif
  296. if VLsavebx
  297. push bx
  298. endif
  299. if VLsavees
  300. push es
  301. endif
  302. if VLATMframe
  303. inc bp
  304. push bp
  305. mov bp,sp
  306. push ds ; push ds and pop it off.
  307. pop ds ; (we need to pop DS rather than
  308. ; something fast like pop AX because
  309. ; ATM doesn't preserve DS itself)
  310. else
  311. push bp
  312. mov bp,sp
  313. endif
  314. push offset VLnameerror ; push address of error handler
  315. VLframe = 1
  316. endif
  317. endm
  318. ;---------------------------------------------------------------------------
  319. ; _ChkName
  320. ;
  321. ; Ensure name was specified
  322. _ChkName macro name
  323. ifb <name>
  324. _print <Missing parameter name in >,%VLiname
  325. endif
  326. endm
  327. ;---------------------------------------------------------------------------
  328. ; _ParmOpts
  329. ;
  330. ; Parse parameter option flags
  331. ;
  332. _ParmOpts macro opts
  333. VLnogenparm = VLnogenpall
  334. irp opt,<opts>
  335. ifidni <opt>,<DEBUGONLY>
  336. ifndef DEBUG
  337. VLnogenparm = 1
  338. endif
  339. ifidni <opt>,<NOGEN>
  340. VLnogenparm = 1
  341. endif
  342. endif
  343. endm
  344. endm
  345. ;---------------------------------------------------------------------------
  346. ; _DefParm name,cb,opts
  347. ;
  348. ; Take care of default parameter stuff, such as defining argument.
  349. ;
  350. _DP_Add macro old,new
  351. ifb <old>
  352. VLplist equ <new>
  353. else
  354. VLplist equ <old,new>
  355. endif
  356. endm
  357. _DefParm macro name,cb,opts
  358. _ChkName <name>
  359. _ParmOpts <opts>
  360. if VLcargs
  361. concat _P_&name,<[bp]+6+>,%(VLcbparms+VLsavees+VLsavebx)
  362. VLcbparms=VLcbparms+(cb)
  363. else
  364. VLcbparms=VLcbparms+(cb)
  365. concat _P_&name,<[bp]+6->,%VLcbparms,<+>,%(VLnamecbparms+VLsavees+VLsavebx)
  366. endif
  367. _DP_Add %VLplist,<_P_&name>
  368. VLgen = 1
  369. if VLnogenparm or VLnogen
  370. VLgen = 0
  371. endif
  372. endm
  373. ;----------------------------------------------------------------------------
  374. ;
  375. ; _GenParm name, cb, opts
  376. ;
  377. _GenParm macro name,cb,opts
  378. _DefParm <name>,<cb>,<opts>
  379. if VLgen
  380. _FlsFrame
  381. endif
  382. endm
  383. lcall2 macro op,label,seg
  384. op label&seg
  385. endm
  386. lcall macro label
  387. lcall2 <call>,<label>,%VLseg
  388. endm
  389. ljmp macro label
  390. lcall2 <jmp>,<label>,%VLseg
  391. endm
  392. ;
  393. ; _PurgeParms - purge list of parameters we've defined
  394. ;
  395. _PurgeParms macro list
  396. irp sym,<list>
  397. sym equ <>
  398. endm
  399. endm
  400. ;---------------------------------------------------------------------------
  401. ; LAYER_START
  402. ;
  403. ; Used before any VL invocations
  404. ;
  405. LAYER_START macro
  406. assumes ds,DATA
  407. endm
  408. ;---------------------------------------------------------------------------
  409. ; LAYER_END
  410. ;
  411. ; Ends all VL definitions
  412. ;
  413. LAYER_END macro
  414. if VLsopen
  415. ENDSTRUCT
  416. endif
  417. if VLopen
  418. APIEND
  419. endif
  420. if VLerrnotinvoked
  421. APIERR
  422. endif
  423. endm
  424. ;=========================================================================
  425. ;
  426. ; Structure related macros
  427. ;
  428. ; Structure globals
  429. VLsopen =0
  430. ;
  431. ; STRUCT - begins a structure declaration
  432. ;
  433. STRUCT macro name,opts
  434. if VLsopen
  435. ENDSTRUCT
  436. endif
  437. VLsopen=1
  438. concat VLcbs,<VLcbs>,name
  439. VLcbstruct = 0
  440. endm
  441. ;
  442. ; ENDSTRUCT macro - terminates a STRUCT declaration
  443. ;
  444. ENDSTRUCT macro
  445. equate %VLcbs,%VLcbstruct
  446. VLsopen =0
  447. endm
  448. ;
  449. ; Define simple field macro, given:
  450. ; f = macro name
  451. ; cb = size of field
  452. ;
  453. _SSize macro cb,opts
  454. VLcbstruct = VLcbstruct + (cb)
  455. endm
  456. _DefSimpleF macro f,cb
  457. f &macro name,opts
  458. equate _F_&&name,%VLcbstruct
  459. _SSize cb
  460. &endm
  461. endm
  462. _DefSimpleF F_char,1
  463. _DefSimpleF F_BYTE,1
  464. _DefSimpleF F_int,2
  465. _DefSimpleF F_WORD,2
  466. _DefSimpleF F_BOOL,2
  467. _DefSimpleF F_FLAGS,2
  468. _DefSimpleF F_LONG,4
  469. _DefSimpleF F_DWORD,4
  470. _DefSimpleF F_intMBZ,2
  471. _DefSimpleF F_DWORDMBZ,4
  472. _DefSimpleF F_LPVOID,4
  473. _DefSimpleF F_CLPSTR,4
  474. _DefSimpleF F_CLPSTR0,4
  475. _DefSimpleF F_LPSTR,4
  476. _DefSimpleF F_POINT,4
  477. _DefSimpleF F_RECT,8
  478. ifdef WOW
  479. _DefSimpleF F_LARGEPOINT,8
  480. endif
  481. F_RGB macro name,cb,opts
  482. equate _F_&name,%VLcbstruct
  483. _SSize cb
  484. endm
  485. F_RGCH equ <F_RGB>
  486. F_RGW macro name,cw,opts
  487. equate _F_&name,%VLcbstruct
  488. _SSize (cw*2)
  489. endm
  490. ;
  491. ; Generate a P_?LP???? macro, given:
  492. ;
  493. ; n = parameter macro name (e.g., P_LPRECT)
  494. ; r = handler routine name (e.g., LP)
  495. ; cb = size of buffer
  496. ;
  497. ; The generated macro checks only whether the
  498. ; buffer is big enough.
  499. ;
  500. _GenLP macro n,r,cb
  501. &n &macro name,opts
  502. _GenParm <name>,4,<opts>
  503. if VLgen
  504. mov ax,_P_&&name
  505. mov cx,_P_&&name+2
  506. mov bx,cb
  507. lcall &r
  508. _gensub <LP>
  509. endif
  510. &endm
  511. endm
  512. ;=========================================================================
  513. ;
  514. ; Generic parameter macros
  515. ;
  516. P_2 macro name, opts
  517. _DefParm <name>,2,<opts>
  518. endm
  519. P_4 macro name, opts
  520. _DefParm <name>,4,<opts>
  521. endm
  522. P_8 macro name, opts
  523. _DefParm <name>,8,<opts>
  524. endm
  525. P_char equ <P_2>
  526. P_int equ <P_2>
  527. P_BYTE equ <P_2>
  528. P_BOOL equ <P_2>
  529. P_WORD equ <P_2>
  530. P_WORDMBZ equ <P_2>
  531. P_WORDMBNZ equ <P_2>
  532. P_LONG equ <P_4>
  533. P_DWORD equ <P_4>
  534. ;
  535. ; Generic handle
  536. ;
  537. P_H macro name, opts
  538. _GenParm <name>,2,<opts>
  539. if VLgen
  540. ; mov ax,_P_&name
  541. ; lcall H
  542. ; _gensub H
  543. endif
  544. endm
  545. ;
  546. ; Generic handle or NULL
  547. ;
  548. P_H0 equ <P_2>
  549. ;
  550. ; Ensure signed value is min <= value <= max
  551. ;
  552. P_RVALUE macro name, min, max, opts
  553. local valok
  554. _GenParm <name>,2,<opts>
  555. if VLgen
  556. mov ax,_P_&name
  557. cmp ax,min
  558. jl @F
  559. cmp ax,max
  560. jle valok
  561. @@:
  562. mov bx,ERR_BAD_VALUE or ERR_WARNING
  563. lcall Inval_Param_
  564. valok:
  565. endif
  566. endm
  567. ;
  568. ; Ensure signed value is 0 <= value <= max
  569. ;
  570. P_VALUE macro name, max, opts
  571. _GenParm <name>,2,<opts>
  572. if VLgen
  573. mov ax,_P_&name
  574. cmp ax,max
  575. jbe @F ;; unsigned comparison to catch < 0.
  576. mov bx,ERR_BAD_VALUE or ERR_WARNING
  577. lcall Inval_Param_
  578. @@:
  579. endif
  580. endm
  581. ;
  582. ; Ensure unsigned value is value <= max
  583. ;
  584. P_UVALUE equ <P_VALUE>
  585. ;
  586. ; Ensure signed value is 0 <= value <= max
  587. ;
  588. P_VALUEW macro name, max, opts
  589. _GenParm <name>,2,<opts>
  590. if VLgen
  591. mov ax,_P_&name
  592. cmp ax,max
  593. jbe @F ;; unsigned comparison to catch < 0.
  594. mov bx,ERR_BAD_VALUE or ERR_WARNING
  595. lcall Inval_Param_
  596. @@:
  597. endif
  598. endm
  599. ;
  600. ; Ensure unsigned value is value <= max
  601. ;
  602. P_UVALUEW equ <P_VALUEW>
  603. ;
  604. ; Ensure signed byte value is min <= value <= max
  605. ;
  606. if 0
  607. P_BVALUE macro name,max,opts
  608. _GenParm <name>,2,<opts>
  609. if VLGen
  610. mov al,_P_&name
  611. cmp al,max
  612. jle @F
  613. lcall ErrorBValue
  614. @@:
  615. endif
  616. endm
  617. else
  618. P_BVALUE equ <P_2>
  619. endif
  620. ;
  621. ; Ensure that no incorrect bits are set in a flags word
  622. ; (i.e., (name & ~valid) == 0)
  623. ;
  624. P_FLAGS macro name, valid, opts
  625. _DefParm <name>,2,<opts>
  626. if not(valid)
  627. if VLgen
  628. _FlsFrame
  629. mov ax,_P_&name
  630. ife (low(not(valid)))
  631. test ah,high(not(valid))
  632. else
  633. ife (high(not(valid)))
  634. test al,low(not(valid))
  635. else
  636. test ax,not(valid)
  637. endif
  638. endif
  639. jz @F
  640. mov bx,ERR_BAD_FLAGS or ERR_WARNING
  641. lcall Inval_Param_
  642. @@:
  643. endif
  644. endif
  645. endm
  646. ;
  647. ; Ensure that no incorrect bits are set in a flags dword
  648. ; (i.e., (name & ~valid) == 0)
  649. ;
  650. P_DFLAGS macro name, valid_l, valid_h, opts
  651. local flagok
  652. _DefParm <name>,4,<opts>
  653. if not(valid_l) or not(valid_h)
  654. if VLgen
  655. _FlsFrame
  656. mov ax,_P_&name
  657. mov cx,_P_&name+2
  658. if not(valid_l)
  659. test ax,not(valid_l)
  660. if not(valid_h)
  661. jnz @F
  662. else
  663. jz flagok
  664. endif
  665. endif
  666. if not(valid_h)
  667. test cx,not(valid_h)
  668. jz flagok
  669. @@:
  670. endif
  671. mov bx,ERR_BAD_DFLAGS or ERR_WARNING
  672. lcall Inval_Param_
  673. flagok:
  674. endif
  675. endif
  676. endm
  677. ;
  678. ; P_LPFN - function pointer
  679. ; P_LPFN0 - function pointer or NULL
  680. ;
  681. P_LPFN macro name, opts
  682. _GenParm <name>,4,<opts>
  683. if VLgen
  684. mov ax,_P_&name
  685. mov cx,_P_&name+2
  686. lcall LPFN
  687. _gensub LPFN
  688. endif
  689. endm
  690. P_LPFN0 macro name, opts
  691. _GenParm <name>,4,<opts>
  692. if VLgen
  693. mov ax,_P_&name
  694. mov cx,_P_&name+2
  695. lcall LPFN0
  696. _gensub LPFN
  697. endif
  698. endm
  699. _GenBuf macro p,r
  700. P_&p &macro lpch, cch, opts
  701. _DefParm <lpch>,4,<opts>
  702. _DefParm <cch>,2,<opts>
  703. if VLgen
  704. _FlsFrame
  705. mov ax,_P_&&lpch
  706. mov cx,_P_&&lpch+2
  707. mov bx,_P_&&cch
  708. lcall &r
  709. _gensub LP
  710. endif
  711. &endm
  712. endm
  713. _GenBufspl macro p,r
  714. P_&p &macro lpch, cch, opts
  715. _DefParm <lpch>,4,<opts>
  716. _DefParm <cch>,2,<opts>
  717. if VLgen
  718. _FlsFrame
  719. mov ax,_P_&&lpch
  720. mov cx,_P_&&lpch+2
  721. lea bx,_P_&&cch
  722. lcall &r
  723. _gensub LPBUF
  724. endif
  725. &endm
  726. endm
  727. _GenBufspl <LPBUFFER>,<LPBUF>
  728. _GenBuf <CLPBUFFER>,<CLP>
  729. _GenBufspl <LPBUFFER0>,<LPBUF0>
  730. _GenBuf <CLPBUFFER0>,<CLP0>
  731. ;
  732. ; If pszBuf is valid, set its first byte to 0
  733. ;
  734. E_SETEMPTY macro pszBuf,cchBuf,opts
  735. push bp
  736. mov bp,sp
  737. mov cx,_P_&cchBuf
  738. mov bx,_P_&pszBuf
  739. mov dx,_P_&pszBuf+2
  740. pop bp
  741. lcall SETEMPTY
  742. _gensub SETEMPTY
  743. endm
  744. ; Same as above, but with no supplied count
  745. ;
  746. E_SETEMPTYNC macro pszBuf,opts
  747. push bp
  748. mov bp,sp
  749. mov cx,1
  750. mov bx,_P_&pszBuf
  751. mov dx,_P_&pszBuf+2
  752. pop bp
  753. lcall SETEMPTY
  754. _gensub SETEMPTY
  755. endm
  756. _GenLP <P_LPSTR>,<LP>,1
  757. _GenLP <P_LPSTR0>,<LP0>,1
  758. P_CLPSTR macro name,cch,opts
  759. _GenParm <name>,4,<opts>
  760. if VLgen
  761. mov ax,_P_&name
  762. mov cx,_P_&name+2
  763. ifb <cch>
  764. mov bx,-1
  765. else
  766. mov bx,cch
  767. endif
  768. lcall CLPSZ
  769. _gensub LPSZ
  770. endif
  771. endm
  772. P_CLPSTR0 macro name,cch,opts
  773. _GenParm <name>,4,<opts>
  774. if VLgen
  775. mov ax,_P_&name
  776. mov cx,_P_&name+2
  777. ifb <cch>
  778. mov bx,-1
  779. else
  780. mov bx,cch
  781. endif
  782. lcall CLPSZ0
  783. _gensub LPSZ
  784. endif
  785. endm
  786. _GenLP <P_LPVOID>,<LP>,1
  787. _GenLP <P_LPVOID0>,<LP0>,1
  788. _GenLP <P_CLPVOID>,<CLP>,1
  789. _GenLP <P_CLPVOID0>,<CLP0>,1
  790. _GenLP <P_LPBYTE>,<LP>,1
  791. _GenLP <P_LPBYTE0>,<LP0>,1
  792. _GenLP <P_CLPBYTE>,<CLP>,1
  793. _GenLP <P_CLPBYTE0>,<CLP0>,1
  794. _GenLP <P_LPINT>,<LP>,2
  795. _GenLP <P_LPINT0>,<LP0>,2
  796. _GenLP <P_CLPINT>,<CLP>,2
  797. _GenLP <P_CLPINT0>,<CLP0>,2
  798. _GenLP <P_LPWORD>,<LP>,2
  799. _GenLP <P_LPWORD0>,<LP0>,2
  800. _GenLP <P_CLPWORD>,<CLP>,2
  801. _GenLP <P_CLPWORD0>,<CLP0>,2
  802. _GenLP <P_LPBOOL>,<LP>,2
  803. _GenLP <P_LPBOOL0>,<LP0>,2
  804. _GenLP <P_CLPBOOL>,<CLP>,2
  805. _GenLP <P_CLPBOOL0>,<CLP0>,2
  806. _GenLP <P_LPLONG>,<LP>,4
  807. _GenLP <P_LPLONG0>,<LP0>,4
  808. _GenLP <P_CLPLONG>,<CLP>,4
  809. _GenLP <P_CLPLONG0>,<CLP0>,4
  810. _GenLP <P_LPDWORD>,<LP>,4
  811. _GenLP <P_LPDWORD0>,<LP0>,4
  812. _GenLP <P_CLPDWORD>,<CLP>,4
  813. _GenLP <P_CLPDWORD0>,<CLP0>,4
  814. ;=======================================================================
  815. ;
  816. ; Common USER types
  817. ;
  818. STRUCT <POINT>
  819. F_int x
  820. F_int y
  821. ENDSTRUCT
  822. STRUCT <LARGEPOINT>
  823. F_LONG x
  824. F_LONG y
  825. ENDSTRUCT
  826. _GenLP <P_LPPOINT>,<LP>,%VLcbsPOINT
  827. _GenLP <P_LPPOINT0>,<LP0>,%VLcbsPOINT
  828. _GenLP <P_CLPPOINT>,<CLP>,%VLcbsPOINT
  829. _GenLP <P_CLPPOINT0>,<CLP0>,%VLcbsPOINT
  830. P_POINT equ <P_4>
  831. _GenLP <P_LPLARGEPOINT>,<LP>,%VLcbsLARGEPOINT
  832. P_LARGEPOINT equ <P_8>
  833. STRUCT <RECT>
  834. F_int left
  835. F_int top
  836. F_int right
  837. F_int bottom
  838. ENDSTRUCT
  839. _GenLP <P_LPRECT>,<LP>,%VLcbsRECT
  840. _GenLP <P_LPRECT0>,<LP0>,%VLcbsRECT
  841. _GenLP <P_CLPRECT>,<CLP>,%VLcbsRECT
  842. _GenLP <P_CLPRECT0>,<CLP0>,%VLcbsRECT
  843. ;=======================================================================
  844. ;
  845. ; Common KERNEL types
  846. ;
  847. P_GHANDLE macro h,opts
  848. _GenParm <h>,2,<opts>
  849. if VLgen
  850. mov ax,_P_&h
  851. lcall GHANDLE
  852. _gensub GHANDLE
  853. endif
  854. endm
  855. P_GHANDLE0 macro h,opts
  856. _GenParm <h>,2,<opts>
  857. if VLgen
  858. mov ax,_P_&h
  859. lcall GHANDLE0
  860. _gensub GHANDLE
  861. endif
  862. endm
  863. P_GHANDLE32 macro h,opts
  864. _GenParm <h>,2,<opts>
  865. if VLgen
  866. mov ax,_P_&h
  867. test al, 0100b ;let zero & BOGUSGDT hInst's through
  868. jz @F
  869. lcall GHANDLE
  870. _gensub GHANDLE
  871. @@:
  872. endif
  873. endm
  874. P_HANDLE equ <P_H>
  875. P_HANDLE0 equ <P_H0>
  876. P_ATOM equ <P_H>
  877. P_HINSTANCE equ <P_GHANDLE>
  878. P_HINSTANCE0 equ <P_GHANDLE0>
  879. P_HINSTANCE32 equ <P_GHANDLE32>
  880. P_HMODULE equ <P_GHANDLE>
  881. P_HMODULE0 equ <P_GHANDLE0>
  882. P_HTASK equ <P_GHANDLE>
  883. P_HTASK0 equ <P_GHANDLE0>
  884. P_CLPSTRATOM macro name, opts
  885. _GenParm <name>,4,<opts>
  886. if VLgen
  887. mov ax,_P_&name
  888. mov cx,_P_&name+2
  889. lcall CLPSTRATOM
  890. _gensub LPSZ
  891. endif
  892. endm
  893. P_CLPSTRATOM0 macro name, opts
  894. _GenParm <name>,4,<opts>
  895. if VLgen
  896. mov ax,_P_&name
  897. mov cx,_P_&name+2
  898. lcall CLPSTRATOM0
  899. _gensub LPSZ
  900. endif
  901. endm
  902. P_CLPSTRRSRC equ <P_CLPSTRATOM>
  903. P_CLPSTRRSRC0 equ <P_CLPSTRATOM0>
  904. ;---------------------------------------------------------------------------
  905. ; LAYER_EXPAND lseg
  906. ;
  907. ; Expands per-segment validation boilerplate code into segment lseg
  908. ;
  909. LAYER_EXPAND macro lseg
  910. .list
  911. .lall
  912. _SwitchSeg &lseg,%VLseg
  913. public VStart&lseg
  914. VStart&lseg:
  915. EXTRA_EXPAND lseg
  916. ;
  917. ; Handle validation
  918. ;
  919. ifdef genH&lseg
  920. public H&lseg
  921. H&lseg:
  922. or ax,ax
  923. jz @F
  924. ret
  925. @@:
  926. mov bx,ERR_BAD_HANDLE
  927. jmp short Inval_Param_&lseg
  928. endif ; genH&lseg
  929. ifdef genGHANDLE&lseg
  930. public GHANDLE0&lseg
  931. GHANDLE0&lseg:
  932. or ax,ax ; accept NULL
  933. jz GHexit&lseg
  934. public GHANDLE&lseg
  935. GHANDLE&lseg:
  936. test al,0100b ; Reject GDT selectors
  937. jz GHerr&lseg
  938. cmp ax,0ffffh ; special case: -1 -> DS
  939. jz GHexit&lseg
  940. lar dx,ax ; is it a valid selector?
  941. jnz GHerr&lseg
  942. GHexit&lseg:
  943. ret
  944. GHerr&lseg:
  945. mov bx,ERR_BAD_GLOBAL_HANDLE
  946. jmp short Inval_Param_&lseg
  947. endif ; genGHANDLE&lseg
  948. ifdef genLPFN&lseg
  949. ;
  950. ; Function pointer validation
  951. ;
  952. public LPFN0&lseg
  953. LPFN0&lseg:
  954. mov bx,ax ; Allow NULL
  955. or bx,cx
  956. jz LPFN_exit&lseg
  957. public LPFN&lseg
  958. LPFN&lseg:
  959. beg_fault_trap LPFNbad&lseg
  960. lar bx,cx
  961. jnz LPFNerr&lseg
  962. test bh,8
  963. jz LPFNerr&lseg
  964. mov es,cx ; validate pointer & offset
  965. mov bx,ax
  966. mov al,es:[bx]
  967. end_fault_trap
  968. ifdef DEBUG
  969. ;
  970. ; Make sure the function is exported by
  971. ; ensuring that the first instructions are NOT
  972. ; push ds, pop ax or mov ax,ds.
  973. ;
  974. mov bx,es:[bx]+2
  975. cmp bx,0581eh ; Push ds, pop ax instructions?
  976. jz LPFNerr&lseg ; Yes, must be an error.
  977. cmp bx,0d88ch ; Mov ax,ds instruction?
  978. jz LPFNerr&lseg ; No, we're ok, so jump ahead
  979. endif ; DEBUG
  980. LPFN_exit&lseg:
  981. ret
  982. LPFNbad&lseg:
  983. fault_fix_stack
  984. LPFNerr&lseg:
  985. mov bx,ERR_BAD_FUNC_PTR
  986. jmp short Inval_Param_&lseg
  987. endif ; genLPFN&lseg
  988. public Inval_Param_&lseg
  989. Inval_Param_&lseg:
  990. pop dx ; convert near return addr to far
  991. push cs
  992. push dx
  993. jmp HandleParamError
  994. ifdef genLP&lseg
  995. public LP0&lseg
  996. LP0&lseg:
  997. or ax,ax ; if cx:ax == NULL, exit
  998. jnz @F
  999. jcxz CLPexit&lseg
  1000. @@:
  1001. public LP&lseg
  1002. LP&lseg:
  1003. beg_fault_trap CLPbad&lseg
  1004. mov es,cx
  1005. or bx,bx ; cb == 0?
  1006. jz CLPexit&lseg ; yes: just check selector
  1007. dec bx
  1008. add bx,ax
  1009. jc CLPbad1&lseg ; check 16 bit overflow
  1010. or byte ptr es:[bx],0 ; check write permission, limit
  1011. end_fault_trap
  1012. ret
  1013. public CLP0&lseg
  1014. CLP0&lseg:
  1015. or ax,ax ; Accept ax:cx == 0
  1016. jnz @F
  1017. jcxz CLPexit&lseg
  1018. @@:
  1019. public CLP&lseg
  1020. CLP&lseg:
  1021. beg_fault_trap CLPbad&lseg
  1022. mov es,cx
  1023. or bx,bx ; cb == 0?
  1024. jz CLPexit&lseg ; yes: just check selector
  1025. dec bx
  1026. add bx,ax
  1027. jc CLPbad1&lseg ; check 16 bit overflow
  1028. mov bl,es:[bx] ; check read permission, limit
  1029. end_fault_trap
  1030. public CLPexit&lseg
  1031. CLPexit&lseg:
  1032. ret
  1033. CLPbad&lseg:
  1034. fault_fix_stack
  1035. CLPbad1&lseg:
  1036. mov bx,ERR_BAD_PTR
  1037. jmp Inval_Param_&lseg
  1038. endif ; genLP&lseg
  1039. ifdef genLPBUF&lseg
  1040. public LPBUF0&lseg
  1041. LPBUF0&lseg:
  1042. or ax,ax ; if cx:ax == NULL, exit
  1043. jnz @F
  1044. jcxz LPBUFexit&lseg
  1045. @@:
  1046. public LPBUF&lseg
  1047. LPBUF&lseg:
  1048. beg_fault_trap LPBUFbad&lseg
  1049. mov es,cx
  1050. mov cx, word ptr ss:[bx] ; cb == 0?
  1051. jcxz LPBUFexit&lseg ; yes: just check selector
  1052. mov dx, bx
  1053. mov bx, ax
  1054. or byte ptr es:[bx],0 ; check write permission, start
  1055. mov bx, dx
  1056. LPBUFpast1&lseg:
  1057. dec cx
  1058. add cx,ax
  1059. jnc @f ; 16-bit overflow
  1060. mov bx, 0ffffh
  1061. mov cx, bx
  1062. or byte ptr es:[bx],0 ; check write permission, 64k-1
  1063. jmp LPBUFov&lseg
  1064. @@:
  1065. mov bx, cx
  1066. or byte ptr es:[bx],0 ; check write permission, end
  1067. ret
  1068. end_fault_trap
  1069. public LPBUFexit&lseg
  1070. LPBUFexit&lseg:
  1071. ret
  1072. LPBUFbad&lseg:
  1073. mov bx, dx
  1074. pop dx ; fault ip
  1075. add sp, 2 ; fault
  1076. cmp dx, offset LPBUFpast1&lseg
  1077. jb LPBUFbad1&lseg
  1078. mov dx, es
  1079. lsl cx, dx
  1080. jnz LPBUFbad1&lseg ; should not occur, we have loaded es
  1081. LPBUFov&lseg:
  1082. sub cx, ax ; max legal cb
  1083. inc cx
  1084. mov word ptr ss:[bx], cx ; fix cb passed by user on stack
  1085. mov cx, es ; HandleParamError prints cx:ax
  1086. mov bx,ERR_BAD_PTR or ERR_WARNING
  1087. jmp Inval_Param_&lseg
  1088. LPBUFbad1&lseg:
  1089. mov cx, es ; HandleParamError prints cx:ax
  1090. mov bx,ERR_BAD_PTR
  1091. jmp Inval_Param_&lseg
  1092. endif ; genLPBUF&lseg
  1093. ifdef genLPSZ&lseg
  1094. ;
  1095. ; cx:ax -> const pointer to z-terminated string or MAKEINTATOM atom.
  1096. ;
  1097. public CLPSTRATOM0&lseg
  1098. CLPSTRATOM0&lseg:
  1099. jcxz CLPSZexit&lseg ; If selector is NULL, then all is well.
  1100. public CLPSTRATOM&lseg
  1101. CLPSTRATOM&lseg:
  1102. jcxz @F ; if selector == 0, then may be atom.
  1103. mov bx,256 ; max string length of 255 characters.
  1104. jmp short CLPSZ&lseg
  1105. @@:
  1106. or ax,ax ; offset == 0? if so, it's bogus
  1107. jz ErrorStrPtr&lseg
  1108. CLPSZexit&lseg:
  1109. ret
  1110. ;
  1111. ; cx:ax => const pointer to zero-terminated string.
  1112. ; bx => Maximum string length (including zero terminator)
  1113. ;
  1114. public CLPSZ0&lseg
  1115. CLPSZ0&lseg:
  1116. mov dx,ax
  1117. or dx,cx
  1118. jz CLPSZexit&lseg
  1119. public CLPSZ&lseg
  1120. CLPSZ&lseg:
  1121. push di ; preserve these regs
  1122. push cx
  1123. mov dx,ax ; preserve original ax in dx
  1124. beg_fault_trap LPSZfault&lseg
  1125. mov es,cx
  1126. mov di,ax
  1127. xor ax,ax
  1128. mov cx,-1
  1129. cld
  1130. repnz scasb
  1131. end_fault_trap
  1132. neg cx ; cx = string length + 1
  1133. dec cx
  1134. cmp cx,bx ; error if string length + 1 > cchMax
  1135. pop cx ; restore regs before branching
  1136. pop di
  1137. xchg ax,dx
  1138. ja ErrorStrPtr&lseg ; jump if error
  1139. ret
  1140. LPSZfault&lseg:
  1141. fault_fix_stack
  1142. pop cx ; restore regs
  1143. pop di
  1144. xchg ax,dx
  1145. public ErrorStrPtr&lseg
  1146. ErrorStrPtr&lseg:
  1147. mov bx,ERR_BAD_STRING_PTR
  1148. jmp Inval_Param_&lseg
  1149. endif ; genLPSZ&lseg
  1150. ifdef genSETEMPTY&lseg
  1151. public SETEMPTY&lseg
  1152. SETEMPTY&lseg:
  1153. jcxz SETEMPTYexit&lseg ; 0-length buffer: do nothing.
  1154. beg_fault_trap SETEMPTYbad&lseg
  1155. mov es,dx
  1156. mov byte ptr es:[bx],0 ; jam in a zero terminator
  1157. end_fault_trap
  1158. SETEMPTYexit&lseg:
  1159. xor ax,ax
  1160. cwd
  1161. ret
  1162. SETEMPTYbad&lseg:
  1163. fault_fix_stack
  1164. jmp short SETEMPTYexit&lseg
  1165. endif ; genSETEMPTY&lseg
  1166. public VEnd&lseg
  1167. VEnd&lseg:
  1168. sEnd %VLseg
  1169. VLseg equ <>
  1170. endm ;LAYER_EXPAND
  1171. endif ;; IF1