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.

1191 lines
32 KiB

  1. f16ptr typedef ptr far16
  2. f32ptr typedef ptr far32
  3. ;==============================================================================
  4. ; BODY_PARAM_16
  5. ; Macro to generate equate for parameter on stack
  6. ;
  7. ;==============================================================================
  8. BODY_PARAM_16 macro name, offset
  9. name equ <[bp+offsetThkParams+offset]>
  10. endm
  11. ;==============================================================================
  12. ; CB_THRU_COMMON
  13. ; Push address to be called and jump to common entry to 32bit code
  14. ;
  15. ;==============================================================================
  16. CB_THRU_COMMON macro addr
  17. local ret_addr
  18. local log_msg_before
  19. local log_msg_after
  20. externDef W32S_BackTo32:near32
  21. ifdef DEBUG
  22. LogCBThkSL proto near stdcall, psz:DWORD
  23. push offset log_msg_before
  24. call LogCBThkSL
  25. endif
  26. push ret_addr
  27. push addr
  28. ; BUGBUG [KevinR] 12-Oct-1993
  29. ; This hardcoded offset is a hack for M5. We should use a proper kernel
  30. ; dispatcher.
  31. assume fs:nothing
  32. Win16LockCount equ <word ptr fs:[30]> ; BUGBUG from k32share.inc
  33. mov di,-1
  34. xchg di,Win16LockCount
  35. ; PERFORMANCE! is is possible to jump directly thru import thunk
  36. ; W32S_BackTo32 just does a retn
  37. jmp W32S_BackTo32
  38. ifdef DEBUG
  39. log_msg_before db "SL before",0
  40. log_msg_after db "SL after",0
  41. endif
  42. ret_addr:
  43. mov Win16LockCount,di
  44. assume fs:error
  45. ifdef DEBUG
  46. push offset log_msg_after
  47. call LogCBThkSL
  48. endif
  49. endm
  50. ;==============================================================================
  51. ; local macro, maps 32-bit pointer to 16-bit pointer,
  52. ;
  53. ; Guarantees:
  54. ; If &SaveAddr& referenes di, the value of di entering MAP_POINTER
  55. ; is used.
  56. ;==============================================================================
  57. MAP_POINTER macro SaveAddr
  58. lodsd ds:[esi]
  59. push eax
  60. call MapLS
  61. ifnb <SaveAddr>
  62. mov &SaveAddr&,eax
  63. endif
  64. stosd es:[di] ; dst in 16:16 stack
  65. endm
  66. ;==============================================================================
  67. ; local macro, clean up after MAP_POINTER.
  68. ;
  69. ; Guarantees:
  70. ; If &SaveAddr& references si, the value of si entering UMAP_POINTER
  71. ; is used.
  72. ;==============================================================================
  73. UMAP_POINTER macro SaveAddr
  74. ifnb <SaveAddr>
  75. push es
  76. pushd &SaveAddr&
  77. call UnmapLS
  78. pop es
  79. endif
  80. add si,4
  81. add edi,4
  82. endm
  83. ;==============================================================================
  84. ; local macro, gets current process hInstance if null
  85. ; Win32/NT allows NULL hInstance where win3.1 doesn't
  86. ;
  87. ;==============================================================================
  88. MAP_NULL_HINST macro hInst
  89. local not_null
  90. ; externDef GetNullhInst:far16
  91. externDef MaphInstLS:far16
  92. ifnb <hInst>
  93. mov eax, hInst
  94. endif
  95. ; call GetNullhInst
  96. call MaphInstLS
  97. not_null:
  98. endm
  99. ;==============================================================================
  100. ; local macro, gets current process hInstance if null
  101. ; Win32/NT allows NULL hInstance where win3.1 doesn't
  102. ;
  103. ;==============================================================================
  104. UMAP_NULL_HINST macro hInst
  105. local not_null
  106. externDef MaphInstSL:far16
  107. ifnb <hInst>
  108. mov ax, hInst
  109. endif
  110. call MaphInstSL
  111. not_null:
  112. endm
  113. ;==============================================================================
  114. ; Convert either an instance handle, a global Win16 handle or junk.
  115. ; Used by commdlg.
  116. ;==============================================================================
  117. MAP_CD_NULL_HINST macro hInst,isInst
  118. local not_inst,exit
  119. cmp isInst,0
  120. jz not_inst
  121. MAP_NULL_HINST hinst
  122. jmp exit
  123. not_inst: ;"hInst" is really 32-bit junk, or a zero-extended global handle.
  124. ;; No need to do anything: "ax" already contains lo-word.
  125. exit:
  126. endm
  127. ;==============================================================================
  128. ; Convert either an instance handle, a global Win16 handle or junk.
  129. ; Used by commdlg.
  130. ;==============================================================================
  131. UMAP_CD_NULL_HINST macro hInst,isInst
  132. local not_inst,exit
  133. cmp isInst,0
  134. jz not_inst
  135. UMAP_NULL_HINST hinst
  136. jmp exit
  137. not_inst: ;"hInst" is really junk, or a global handle.
  138. ror eax,16
  139. xor ax,ax
  140. ror eax,16
  141. exit:
  142. endm
  143. ;==============================================================================
  144. ; local macro, maps 32-bit call-back function pointer to 16-bit
  145. ; call back function pointer,
  146. ; check if it is a NULL pointer before calling AllocCallBack.
  147. ;==============================================================================
  148. MAP_CALLBACK macro CallBackType:req
  149. lods dword ptr ds:[esi] ;wndproc must have a 16-bit
  150. push bx ;save BX
  151. push es ;save ES
  152. push eax ;push address as parameter
  153. push dword ptr CallBackType ;push cb type as parameter
  154. call AllocCallback ;DX:AX = 16-bit cb address
  155. pop es ;restore ES
  156. pop bx ;restore BX
  157. stos dword ptr es:[di] ;pass on NULL pointer
  158. endm
  159. ;==============================================================================
  160. ; local macro, free resources allocated for a call-back function
  161. ; check if it is a NULL pointer before calling FreeCallBack.
  162. ; eax contains the 32-bit address of the mapped call-back function
  163. ;==============================================================================
  164. FREE_CALLBACK macro iCallbackType:req
  165. endm
  166. ;==============================================================================
  167. ; local macro, maps byte size field to byte size field
  168. ;==============================================================================
  169. MAP_BYTETOBYTE macro
  170. lodsb ds:[esi]
  171. stosb es:[di]
  172. endm
  173. ;==============================================================================
  174. ; local macro, maps byte size field to byte size field
  175. ;==============================================================================
  176. UMAP_BYTETOBYTE macro
  177. lodsb ds:[si]
  178. stosb es:[edi]
  179. endm
  180. ;==============================================================================
  181. ; local macro, maps word size field to word size field
  182. ;==============================================================================
  183. MAP_WORDTOWORD macro
  184. lodsw ds:[esi]
  185. stosw es:[di]
  186. endm
  187. ;==============================================================================
  188. ; local macro, maps word size field to word size field
  189. ;==============================================================================
  190. UMAP_WORDTOWORD macro
  191. lodsw ds:[si]
  192. stosw es:[edi]
  193. endm
  194. ;==============================================================================
  195. ; local macro, maps dword size field to word size field
  196. ;==============================================================================
  197. MAP_DWORDTOWORD macro
  198. lodsd ds:[esi]
  199. stosw es:[di]
  200. endm
  201. ;==============================================================================
  202. ; local macro, maps dword size field to word size field
  203. ;==============================================================================
  204. UMAP_WORDTODWORD macro
  205. lodsw ds:[si]
  206. movzx eax,ax
  207. stosd es:[edi]
  208. endm
  209. ;==============================================================================
  210. ; local macro, maps long size field to int size field
  211. ;==============================================================================
  212. MAP_LONGTOINT macro
  213. lodsd ds:[esi]
  214. stosw es:[di]
  215. endm
  216. ;==============================================================================
  217. ; local macro, maps int size field to long size field
  218. ;==============================================================================
  219. UMAP_INTTOLONG macro
  220. lodsw ds:[si]
  221. cwde
  222. stosd es:[edi]
  223. endm
  224. ;==============================================================================
  225. ; local macro, maps dword size field to dword size field
  226. ;==============================================================================
  227. MAP_DWORDTODWORD macro
  228. movsd es:[di], ds:[esi]
  229. endm
  230. ;==============================================================================
  231. ; local macro, maps dword size field to dword size field
  232. ;==============================================================================
  233. UMAP_DWORDTODWORD macro
  234. movsd es:[edi], ds:[si]
  235. endm
  236. ;==============================================================================
  237. ; The following are variants of the above macros that are better suited for
  238. ; repacking structures in-place.
  239. ;==============================================================================
  240. ;==============================================================================
  241. ; local macro, maps 32-bit call-back function pointer to 16-bit
  242. ; call back function pointer,
  243. ; check if it is a NULL pointer before calling AllocCallBack.
  244. ;==============================================================================
  245. MAP_CALLBACK_32_16_IP macro reg:=<ds>,CallBackType:req
  246. lods dword ptr reg:[si] ;wndproc must have a 16-bit
  247. push bx
  248. push es
  249. push eax
  250. push dword ptr CallBackType
  251. call AllocCallback
  252. pop es
  253. pop bx
  254. stosd
  255. endm
  256. ;==============================================================================
  257. ; local macro, maps 16-bit call-back function pointer to 32-bit
  258. ; call back function pointer,
  259. ; check if it is a NULL pointer before calling AllocCallback.
  260. ;
  261. ; ASSUMES DIRECTION FLAG DOWN, i.e. STD.
  262. ;==============================================================================
  263. MAP_CALLBACK_16_32_IP macro reg:=<ds>,CallBackType:req
  264. lods dword ptr reg:[si] ;wndproc must have a 16-bit
  265. push bx
  266. push es
  267. push eax
  268. push dword ptr CallBackType
  269. call AllocCallback32
  270. pop es
  271. pop bx
  272. stosd
  273. endm
  274. ;==============================================================================
  275. ; local macro, maps 32-bit pointer to 16-bit pointer,
  276. ;==============================================================================
  277. MAP_POINTER_32_16_IP macro reg:=<ds>
  278. lodsd reg:[si]
  279. push eax
  280. call MapLS
  281. stosd es:[di]
  282. endm
  283. ;==============================================================================
  284. ; MAP_HINST_32_16_IP
  285. ; Map an instance handle from 32->16 in-place. If the original value is 0,
  286. ; replace it with the instance handle from win32s16.dll.
  287. ;
  288. ; Assumes ds = _DATA.
  289. ;==============================================================================
  290. MAP_HINST_32_16_IP macro reg:=<ds>
  291. local have_hinst
  292. lods dword ptr reg:[si] ; convert hinst to word
  293. or ax,ax ; translate to hComboInst if
  294. jnz have_hinst ; null
  295. mov ax,hComboInst
  296. have_hinst:
  297. stosw
  298. endm
  299. ;==============================================================================
  300. ; MAP_HINST_16_32_IP
  301. ; Map an instance handle from 16->32 in-place. If the original value is
  302. ; hComboInst, replace it with 0.
  303. ;
  304. ; Assumes ds = _DATA.
  305. ;==============================================================================
  306. MAP_HINST_16_32_IP macro reg:=<ds>
  307. local have_hinst
  308. lods word ptr reg:[si] ; convert hinst to word
  309. cmp ax,hComboInst ; translate to null if
  310. jnz have_hinst ; hComboInst
  311. sub ax,ax
  312. have_hinst:
  313. movzx eax,ax
  314. stosd
  315. endm
  316. ;==============================================================================
  317. ; local macro, maps word size field to word size field
  318. ;==============================================================================
  319. MAP_WORDTOWORD_IP macro reg:=<ds>
  320. movsw es:[di], reg:[si]
  321. endm
  322. ;==============================================================================
  323. ; local macro, maps dword size field to word size field
  324. ;==============================================================================
  325. MAP_DWORDTOWORD_IP macro reg:=<ds>
  326. lodsd reg:[si]
  327. stosw es:[di]
  328. endm
  329. ;==============================================================================
  330. ; local macro, maps dword size field to word size field
  331. ;==============================================================================
  332. MAP_LONGTOINT_IP macro reg:=<ds>
  333. lodsd reg:[si]
  334. stosw es:[di]
  335. endm
  336. ;==============================================================================
  337. ; local macro, maps dword size field to dword size field
  338. ;==============================================================================
  339. MAP_DWORDTODWORD_IP macro reg:=<ds>
  340. movsd es:[di], reg:[si]
  341. endm
  342. ;==============================================================================
  343. ; local macro, maps word size field to dword size field by zero-extension
  344. ;==============================================================================
  345. MAP_WORDTODWORD_IP macro reg:=<ds>
  346. lodsw reg:[si]
  347. movzx eax,ax
  348. stosd es:[di]
  349. endm
  350. ;==============================================================================
  351. ; local macro, maps word size field to dword size field by sign-extension
  352. ;==============================================================================
  353. MAP_INTTOLONG_IP macro reg:=<ds>
  354. lodsw reg:[si]
  355. cwde
  356. stosd es:[di]
  357. endm
  358. ;==============================================================================
  359. ; save all 16-bit registers, except dx:ax
  360. ;
  361. ;==============================================================================
  362. SAVEALL macro
  363. push cx ; save all 16-bit registers, except dx:ax
  364. push bx
  365. push bp
  366. push si
  367. push di
  368. push ds
  369. push es
  370. endm
  371. ;==============================================================================
  372. ; restore all 16-bit registers, except dx:ax
  373. ;
  374. ;==============================================================================
  375. RESTOREALL macro StackType:=<Stack16>
  376. POPW es ; restore all 16-bit registers, except dx:ax
  377. CHECKW ds, StackType
  378. POPW ds
  379. CHECKW di, StackType
  380. pop di
  381. CHECKW si, StackType
  382. pop si
  383. CHECKW bp, StackType
  384. pop bp
  385. pop bx
  386. pop cx
  387. endm
  388. ;==============================================================================
  389. ; save all 32-bit registers, except eax
  390. ;
  391. ;==============================================================================
  392. SAVEALL32 macro
  393. push edx ;save all 32-bit registers except eax
  394. push ecx
  395. push ebx
  396. push ebp
  397. push esi
  398. push edi
  399. push ds
  400. push es
  401. endm
  402. ;==============================================================================
  403. ; restore all 32-bit registers, except eax
  404. ;
  405. ;==============================================================================
  406. RESTOREALL32 macro StackType:=<Stack16>
  407. POPD es ; restore all 32-bit registers, except eax
  408. CHECKD ds, StackType
  409. POPD ds
  410. CHECKD edi, StackType
  411. pop edi
  412. CHECKD esi, StackType
  413. pop esi
  414. CHECKD ebp, StackType
  415. pop ebp
  416. CHECKD ebx, StackType
  417. pop ebx
  418. pop ecx
  419. pop edx
  420. endm
  421. ;==============================================================================
  422. ; test two text macros for equality
  423. ;
  424. ;
  425. ;==============================================================================
  426. TextEqual? macro Text_1, Text_2
  427. ifidni <Text_1>, <Text_2>
  428. exitm <not 0>
  429. endif
  430. exitm <0>
  431. endm
  432. ;==============================================================================
  433. ; test two text macros for difference
  434. ;
  435. ;
  436. ;==============================================================================
  437. TextDiff? macro Text_1, Text_2
  438. ifidni <Text_1>, <Text_2>
  439. exitm <0>
  440. endif
  441. exitm <not 0>
  442. endm
  443. ;==============================================================================
  444. ; check a word on top of the stack
  445. ; if not equal, break
  446. ;
  447. ;==============================================================================
  448. CHECKW macro CurrentReg, StackType:=<Stack16>
  449. local skip_int3
  450. local skip_another_int3
  451. if (@WordSize eq 4) and TextDiff? (&StackType&,Stack16)
  452. push eax
  453. mov ax,&CurrentReg&
  454. cmp ax,word ptr [esp+4]
  455. pop eax
  456. je skip_int3
  457. int 3
  458. skip_int3:
  459. else
  460. push bp
  461. push ax
  462. mov ax,&CurrentReg&
  463. mov bp,sp
  464. and ebp,0ffffh
  465. cmp ax,word ptr [ebp+4]
  466. pop ax
  467. pop bp
  468. je skip_another_int3
  469. int 3
  470. skip_another_int3:
  471. endif
  472. endm
  473. ;==============================================================================
  474. ; check a dword on top of the stack
  475. ; if not equal, break
  476. ;
  477. ;==============================================================================
  478. CHECKD macro CurrentReg, StackType:=<Stack32>
  479. local skip_int3
  480. local skip_another_int3
  481. if 0
  482. ;!!! fix this
  483. if (@WordSize eq 4) and TextDiff? (&StackType&,Stack32)
  484. push eax
  485. mov ax,&CurrentReg&
  486. cmp ax,word ptr [esp+4]
  487. pop eax
  488. je skip_int3
  489. int 3
  490. skip_int3:
  491. else
  492. push bp
  493. push ax
  494. mov ax,&CurrentReg&
  495. mov bp,sp
  496. and ebp,0ffffh
  497. cmp ax,word ptr [ebp+4]
  498. pop ax
  499. pop bp
  500. je skip_another_int3
  501. int 3
  502. skip_another_int3:
  503. endif
  504. endif
  505. endm
  506. ;==============================================================================
  507. ; pop word
  508. ;
  509. ;==============================================================================
  510. POPW macro SegReg
  511. if @WordSize eq 4
  512. db 66h
  513. endif
  514. pop SegReg
  515. endm
  516. ;==============================================================================
  517. ; pop dword
  518. ;
  519. ;==============================================================================
  520. POPD macro SegReg
  521. if @WordSize eq 2
  522. db 66h
  523. endif
  524. pop SegReg
  525. endm
  526. ;==============================================================================
  527. ; operand-size override
  528. ;
  529. ;==============================================================================
  530. OTHER_OPERAND_SIZE macro arg
  531. db 66h
  532. arg
  533. endm
  534. ;==============================================================================
  535. ; address-size override
  536. ;
  537. ;==============================================================================
  538. OTHER_ADDRESS_SIZE macro arg
  539. db 67h
  540. arg
  541. endm
  542. ;==============================================================================
  543. ; pop 16
  544. ;
  545. ;==============================================================================
  546. POP16 macro Reg
  547. if @WordSize eq 4
  548. irp curreg,<cs,ds,ss,es,fs,gs>
  549. ifidni <curreg>,<Reg>
  550. db 66h
  551. endif
  552. endm
  553. endif
  554. pop Reg
  555. endm
  556. ;==============================================================================
  557. ; allocate and public a byte flag
  558. ;
  559. ;==============================================================================
  560. PubByte macro name, value
  561. public name
  562. name db value
  563. endm
  564. ;==============================================================================
  565. ; log a 16=>32 api call
  566. ;
  567. ;==============================================================================
  568. APILOGSL macro argName
  569. local exit,szLogMsg
  570. ifdef DEBUG
  571. LogApiThkSL proto near stdcall, psz:dword
  572. push offset szLogMsg
  573. call LogApiThkSL
  574. jmp exit
  575. szLogMsg db '&argName&',13,10,0
  576. exit:
  577. endif
  578. endm
  579. ;==============================================================================
  580. ; log a 32=>16 api call, non-flat
  581. ;
  582. ;==============================================================================
  583. APILOGLS macro argName
  584. local exit,szLogMsg
  585. ifdef DEBUG
  586. externDef LogApiThkLS:far16
  587. push ax
  588. push cs
  589. push offset szLogMsg
  590. call LogApiThkLS
  591. pop ax
  592. jmp exit
  593. szLogMsg db '&argName&',13,10,0
  594. exit:
  595. endif
  596. endm
  597. ;==============================================================================
  598. ; log an api call, 16-bit
  599. ;
  600. ; BUGBUG [KevinR] 26-Aug-1993
  601. ; rip out this macro when we get rid of fNewDispatcherLS
  602. ;
  603. ;==============================================================================
  604. APILOG16 macro argName, argUnused, argComment
  605. local exit,szApiName,szComment
  606. ifdef DEBUG
  607. externDef Log16BitThunkCall:far16
  608. dsOffsetInCS CATSTR @code, <CodeData>
  609. push ds
  610. push ax
  611. mov ds,cs:dsOffsetInCS
  612. push cs
  613. push offset szApiName
  614. push cs
  615. push offset szComment
  616. call Log16BitThunkCall
  617. pop ax
  618. pop ds
  619. jmp exit
  620. szApiName db '&argName& ',0
  621. szComment db '&argComment& ',0
  622. exit:
  623. endif
  624. endm
  625. ;==============================================================================
  626. ; log an api call, 32-bit
  627. ;
  628. ;==============================================================================
  629. APILOG macro argName, argFlag
  630. local do_it,done,szApiName
  631. ifdef DEBUG
  632. ;externDef _DbgPrint:near32
  633. ;;If argFlag is nonzero, print out the message.
  634. cmp argFlag&,0
  635. jnz do_it
  636. jmp short done
  637. ;;Define the name here so we can pass it to _DbgPrint.
  638. szApiName db '&argName&',0
  639. do_it:
  640. push offset FLAT:szApiName
  641. push offset FLAT:szApiFmt
  642. ;call _DbgPrint
  643. add esp,2*4
  644. done:
  645. endif
  646. endm
  647. ;==============================================================================
  648. ; log 16-bit api return, in 32-bit code
  649. ;
  650. ;==============================================================================
  651. RETLOG macro argFlag
  652. endm
  653. ;==============================================================================
  654. ; conditionally break
  655. ;
  656. ;==============================================================================
  657. SWITCHABLE_INT3 macro argLabel, argFlag
  658. local skip_int3
  659. externDef argLabel :far16
  660. push ds
  661. push ax
  662. mov ax,seg &argFlag
  663. mov ds,ax
  664. cmp &argFlag,0
  665. je skip_int3
  666. argLabel& label far16
  667. int 3
  668. skip_int3:
  669. pop ax
  670. pop ds
  671. endm
  672. ;==============================================================================
  673. ;
  674. ;
  675. ;==============================================================================
  676. STUB0 macro module, argLabel, nBytes, argComment:=<stub0>
  677. externDef argLabel&16 :far16
  678. argLabel&16 label far16
  679. ifdef FSAVEALL
  680. SAVEALL
  681. endif
  682. APILOG16 argLabel&16, f&module&ApiLog, argComment
  683. ifdef INT3
  684. SWITCHABLE_INT3 argLabel&_stub, f&module&Int3
  685. endif
  686. xor ax,ax
  687. cwd
  688. ifdef FSAVEALL
  689. RESTOREALL
  690. endif
  691. retf &nBytes&
  692. endm
  693. ;==============================================================================
  694. ;
  695. ;
  696. ;==============================================================================
  697. STUB macro module, argLabel, nBytes, nRetAX, argComment:=<stub>
  698. externDef argLabel&16 :far16
  699. externDef PCodeDebug16 :far16
  700. argLabel&16 label far16
  701. ifdef FSAVEALL
  702. SAVEALL
  703. endif
  704. APILOG16 argLabel&16, f&module&ApiLog, argComment nRetAX
  705. ifdef INT3
  706. SWITCHABLE_INT3 argLabel&_stub, f&module&Int3
  707. endif
  708. mov ax,&nRetAX
  709. ifdef FSAVEALL
  710. RESTOREALL
  711. endif
  712. retf nBytes
  713. endm
  714. ;==============================================================================
  715. ; entry code for flat common callback
  716. ;
  717. ;==============================================================================
  718. CALLBACK_PROLOGUE macro
  719. pop eax ; 16:16 callback
  720. pop edx ; eip, API32
  721. push cs ; flat cs
  722. push edx ; eip, API32
  723. push eax ; 16:16 callback
  724. push ebp
  725. mov ebp,esp
  726. push ds ; save registers
  727. push es
  728. push ebx
  729. push edi
  730. push esi
  731. endm
  732. ;==============================================================================
  733. ; exit code for flat common callback
  734. ;
  735. ;==============================================================================
  736. CALLBACK_EPILOGUE macro size
  737. LOCAL bad_esp
  738. ;--------------------------------------------------
  739. ; switch stacks and jump to 16:16 callback
  740. ; when the 16:16 callback does a retf, we will hit our cleanup routine
  741. push dword ptr ADDR_THK_CLEANUP_&size
  742. ; prepare to transfer to the 16-bit callback function
  743. push pCallback16
  744. ; get the ss16 we had when we entered the callback API16
  745. ; make the 16-bit ss:sp point to the same linear address as the flat ss:esp
  746. call UsrQuerySS16
  747. mov esi,eax ; save ss16
  748. push eax
  749. call GetSelectorBase32 ; LATER: LDT lookup
  750. xchg eax,esp
  751. sub eax,esp
  752. jb bad_esp
  753. cmp eax,65535
  754. ja bad_esp
  755. mov ss,si
  756. mov sp,ax
  757. ; effectively, jmp to 16:16 callback
  758. retw
  759. bad_esp:
  760. int 3
  761. endm
  762. ;==============================================================================
  763. ; save flat stack and thunkID
  764. ;
  765. ;==============================================================================
  766. SAVE_STACK_AND_THUNKID macro
  767. lea eax,[addr_registers] ; save flat stack
  768. push ss
  769. push eax
  770. call GetThunkID32
  771. push eax ; save 16:16 thunkID
  772. endm
  773. ;==============================================================================
  774. ; 32-bit callback cleanup code
  775. ;
  776. ;==============================================================================
  777. CALLBACK_CLEANUP32 macro size
  778. externDef CALLBACK_CLEANUP_&size&:near32
  779. CALLBACK_CLEANUP_&size&:
  780. ;;;-----------------------------------------------------------------------
  781. ;;; DO NOT REMOVE THE OVERRIDE PREFIX. IT IS NEEDED TO GET PAST A BUG
  782. ;;; IN A CERTAIN BRAND OF CLONE CHIPS.
  783. ;;;-----------------------------------------------------------------------
  784. lss sp,ss:[ebx]
  785. POP16 ds
  786. POP16 di
  787. POP16 si
  788. POP16 bp
  789. add sp, 8 ; pop dispatcher ptr+index
  790. OTHER_OPERAND_SIZE
  791. retf size ; return to the 16-bit API
  792. endm
  793. ;==============================================================================
  794. ; SetLastError mechanism
  795. ;
  796. ;==============================================================================
  797. SETERROR macro Value:req, Error:req
  798. local done
  799. externDef SetLastError16:far16
  800. cmp ax,Value
  801. jne short done
  802. push dword ptr Error
  803. call SetLastError16
  804. done:
  805. endm
  806. ;-----------------------------------------------------------------------;
  807. ; MoveBytes -- generate code to move n consecutive bytes
  808. ;
  809. ; Entry:
  810. ; DS:ESI --> source
  811. ; ES:EDI --> destination
  812. ;-----------------------------------------------------------------------;
  813. MoveBytes macro n
  814. local q, r
  815. q = n / 4
  816. r = n and 3
  817. if q
  818. if q lt 256
  819. mov ecx,byte ptr q
  820. else
  821. mov ecx,q
  822. endif
  823. rep movs dword ptr es:[edi], dword ptr ds:[esi]
  824. endif
  825. if r
  826. mov ecx,byte ptr r
  827. rep movs byte ptr es:[edi], byte ptr ds:[esi]
  828. endif
  829. endm
  830. ;-----------------------------------------------------------------------;
  831. ; ZeroBytes -- generate optimized code to set n consecutive bytes to 0
  832. ;
  833. ; Entry:
  834. ; ES:EDI --> address at which to start
  835. ;-----------------------------------------------------------------------;
  836. ZeroBytes macro n
  837. local q, r
  838. q = n / 4
  839. r = n and 3
  840. sub eax,eax
  841. if q
  842. if q lt 256
  843. mov ecx,byte ptr q
  844. else
  845. mov ecx,q
  846. endif
  847. rep stos dword ptr es:[edi]
  848. endif
  849. if r
  850. mov ecx,byte ptr r
  851. rep stos byte ptr es:[edi]
  852. endif
  853. endm
  854. ;-----------------------------------------------------------------------;
  855. ; GMH2Sel
  856. ;
  857. ; This macro encapsulates the assumption that a global memory handle
  858. ; in win3.1 is either a selector (if fixed) or a selector with the
  859. ; low bit cleared (if moveable). Therefore, it can be turned into a
  860. ; selector by always setting the low bit.
  861. ;-----------------------------------------------------------------------;
  862. GMH2Sel macro reg:req, regMask1, regMask2
  863. ifb <regMask1>
  864. or reg,1
  865. else
  866. .errb <regMask2>
  867. ;The following sequence uses two mask registers to
  868. ;convert only non-zero values of "reg" to selectors.
  869. mov regMask1,1 ;mov cx,1
  870. cmp reg,regMask1 ;cmp ax,cx C=1 if AX=0
  871. cmc ;cmc C=0 if AX=0
  872. sbb regMask2,regMask2 ;sbb dx,dx DX=0 if AX=0
  873. and regMask1,regMask2 ;and cx,dx CX=0 if AX=0
  874. or reg,regMask1 ;or ax,cx AX=0 if AX=0
  875. endif
  876. endm
  877. ;-----------------------------------------------------------------------;
  878. ; PACK_CALLBACK
  879. ;-----------------------------------------------------------------------;
  880. PACK_CALLBACK macro iOffset,iTempOffset,dwCallbackType
  881. local exit
  882. local not_null
  883. mov esi,[bp+&iOffset&]
  884. or esi,esi
  885. jnz not_null
  886. sub sp,18 ;Space the thunklet would have taken
  887. jmp exit
  888. not_null:
  889. ; Push the following code on the stack:
  890. ;
  891. ; 66 68 xx xx xx xx push imm32 <flat lpCallback>
  892. ; 66 68 xx xx xx xx push imm32 <dwCallbackType>
  893. ; 90 nop ;for convenient
  894. ; EA xx xx xx xx jmp CALLBACK_BODY_16
  895. mov ax,seg CALLBACK_BODY_16
  896. push ax
  897. mov ax,offset CALLBACK_BODY_16
  898. push ax
  899. push 0ea90h
  900. push dword ptr &dwCallbackType&
  901. push 6866h
  902. push esi
  903. push 6866h
  904. push ss
  905. call GetCSAlias
  906. mov [bp-&iTempOffset&],sp
  907. mov [bp-(&iTempOffset&)+2],ax
  908. exit:
  909. endm; PACK_CALLBACK
  910. ;-----------------------------------------------------------------------;
  911. ; UNPACK_CALLBACK
  912. ;-----------------------------------------------------------------------;
  913. UNPACK_CALLBACK macro iOffset,iTempOffset,dwCallbackType
  914. push word ptr [bp-&iTempOffset&+2]
  915. call FreeCSAlias
  916. endm; UNPACK_CALLBACK
  917. ;-----------------------------------------------------------------------;
  918. ; TILE_BUFFER
  919. ;
  920. ; Allocates overlapping tiling selectors for a huge memory block.
  921. ;
  922. ; Inputs:
  923. ; eax: 32-bit linear address (NULL is allowed)
  924. ; ecx: 32-bit buffer size (if 0, eax is treated as NULL)
  925. ;
  926. ; Outputs:
  927. ; eax: upper 16 bits = first selector
  928. ; lower 16 bits = 0 (thus, eax is the 16:16 pointer)
  929. ; ecx: upper 16 bits = first selector (same as upper eax)
  930. ; lower 16 bits = # of selectors allocated
  931. ; CF: 0 = success, 1 = failure.
  932. ;
  933. ; Registers preserved:
  934. ; bp, sp, all segment registers.
  935. ;
  936. ; Special cases:
  937. ; if buffer address is NULL or the size is 0, macro returns
  938. ; eax == ecx == 0, CF = 0.
  939. ; if macro fails, it returns eax == 0, CF = 1.
  940. ;
  941. ; Use UNTILE_BUFFER to deallocate tiling selectors.
  942. ;-----------------------------------------------------------------------;
  943. TILE_BUFFER macro
  944. extern TileBuffer:far16 ;Dynalink to win32c.dll
  945. call TileBuffer
  946. endm ;TILEBUFFER
  947. ;-----------------------------------------------------------------------;
  948. ; UNTILE_BUFFER
  949. ;
  950. ; Releases tiling selectors allocated by TILE_BUFFER.
  951. ;
  952. ; Inputs:
  953. ; ecx == sel:count (as returned by TILE_BUFFER. 00:00 is legal).
  954. ;
  955. ; Outputs:
  956. ; None.
  957. ;
  958. ; Registers preserved:
  959. ; bp, sp, all segment registers
  960. ;
  961. ; Special case:
  962. ; UNTILE_BUFFER does nothing if sel:count == 00:00.
  963. ;-----------------------------------------------------------------------;
  964. UNTILE_BUFFER macro
  965. extern UntileBuffer:far16 ;Dynalink to win32c.dll
  966. call UntileBuffer
  967. endm ;UNTILE_BUFFER