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.

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