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.

549 lines
14 KiB

  1. ;---------------------------------------------------------------------------
  2. ; Optimzed Code Path - on x86 builds effectively excecutes USER32 code.
  3. ;
  4. ; Created:
  5. ; 16-DEC-93 nandurir
  6. ;---------------------------------------------------------------------------
  7. TITLE USER5.ASM
  8. PAGE ,132
  9. .286p
  10. .xlist
  11. include ks386p.inc
  12. .286p
  13. NOEXTERNS=1 ; to suppress including most of the stuff in user.inc
  14. include wow.inc
  15. include wowusr.inc
  16. ;;;;;include cmacros.inc
  17. include user.inc
  18. .list
  19. externFP WOW16Call
  20. createSeg _TEXT,CODE,WORD,PUBLIC,CODE
  21. createSeg _DATA,DATA,WORD,PUBLIC,DATA,DGROUP
  22. defgrp DGROUP,DATA
  23. externFP WowSetCompatHandle
  24. ;---------------------------------------------------------------------------
  25. ; Optimized thunks for x86 only
  26. ;
  27. ;
  28. ;---------------------------------------------------------------------------
  29. ifndef PMODE32
  30. USER16CLIENTTHUNK macro Iapi, api, argtypeslist, returntype, api32, apispecificcode, callserver
  31. sBegin CODE
  32. index = 0
  33. IRP argtype, <argtypeslist>
  34. index = index + 1
  35. ENDM
  36. IFE index
  37. &Iapi &api, 0
  38. ELSE
  39. &Iapi &api
  40. ENDIF
  41. sEnd CODE
  42. endm
  43. else
  44. externFP OutputDebugString
  45. LOGARGS macro apiname
  46. push dx
  47. push ax
  48. push cs
  49. push OFFSET afterlog_&apiname
  50. call OutputDebugString
  51. pop ax
  52. pop dx
  53. jmp short afterlogname_&apiname
  54. afterlog_&apiname: DB 'USER: ','&apiname','()', 0dh, 0ah, 0
  55. afterlogname_&apiname:
  56. endm
  57. ; flat selector values
  58. ;
  59. FLATDS equ KGDT_R3_DATA OR RPL_MASK
  60. FLATFS equ KGDT_R3_TEB OR RPL_MASK
  61. ; set flat ds and fs
  62. ;
  63. SETFLATDSANDFS macro
  64. .386p
  65. mov ax, FLATDS
  66. mov ds, ax
  67. mov ax, FLATFS
  68. mov fs, ax
  69. endm
  70. externFP GetSelectorBase
  71. GETFLATADDRESS macro farpointer
  72. ; check for null
  73. xor dx, dx
  74. mov ax, word ptr &farpointer+2
  75. or ax, ax
  76. jz @F
  77. cCall GetSelectorBase, <ax>
  78. ; check for base address 0
  79. mov cx, ax
  80. or cx, dx
  81. jz @F
  82. ; now its ok
  83. add ax, word ptr &farpointer
  84. adc dx, 0
  85. @@:
  86. endm
  87. ; generates code like: parmW arg1
  88. ;
  89. GENPARAM macro argtype, argname
  90. parm&argtype &argname
  91. endm
  92. pushWORD_DWORD macro argname
  93. movzx eax, &argname
  94. push eax
  95. endm
  96. pushINT_LONG macro argname
  97. movsx eax, &argname
  98. push eax
  99. endm
  100. pushDWORD_DWORD macro argname
  101. push dword ptr &argname
  102. endm
  103. pushPSZ_DWORD macro argname, apiname, argnumber
  104. GETFLATADDRESS &argname
  105. push dx
  106. push ax
  107. IFNB <apiname>
  108. or ax, dx
  109. jnz @F
  110. add sp, argnumber * 4
  111. xor eax, eax
  112. jmp short FailCall_&apiname
  113. @@:
  114. ENDIF
  115. endm
  116. pushHHOOK_DWORD macro argname
  117. push dword ptr -1 ; unreferenced parameter
  118. ; effectively an assertion
  119. endm
  120. pushARG16 macro argname
  121. push &argname
  122. endm
  123. CALLORDECLARE macro typestring, api32, totalbytes
  124. &typestring api32&@&totalbytes
  125. endm
  126. TESTCALLSERVERCONDITION macro
  127. mov edx, DWORD PTR _wow16CsrFlag
  128. test BYTE PTR [edx], 1
  129. endm
  130. ; assumes eax is pointer to the flag
  131. CLEARCALLSERVERCONDITION macro
  132. mov BYTE PTR [edx], 0
  133. endm
  134. ;--------------------------------------------------------------------------
  135. ; Iapi = either DUserThunk or UserThunk
  136. ; api = actual name
  137. ; argtypeslist = list of argument 'types' like <WORD, INT, HWND>
  138. ; api32 = this function is called instead of _Api
  139. ; apispecificcode = flag indicating additional code needed for this api.
  140. ; This is intended for handling 'compatibility'.
  141. ;
  142. ; If this argument is not blank, then there must exist a macro
  143. ; APISPECIFICCODE_api, which expands to the desired code.
  144. ; At present it is included just before the 'return' to
  145. ; the app.
  146. ;
  147. ; callserver = flag indication that it may be necessary to actually call
  148. ; USER32.
  149. ;
  150. ; If this argument is not blank, then there must exist a macro
  151. ; CALLSERVERCONDITION_api which expands to the desired code and
  152. ; clears or sets the zero flag. If ZF is clear, the actual
  153. ; thunk gets called, else nop.
  154. ;
  155. ;
  156. ; generates code similar to:
  157. ;
  158. ; externFP _Api OR Api32
  159. ; sBegin CODE
  160. ; if necessary
  161. ; FUN_WOWApi equ FUN_Api
  162. ; DUserThunk WOWApi, %(size Api16)
  163. ; endif
  164. ;
  165. ; cProc Api, <PUBLIC, FAR, PASCAL>, <ds>
  166. ; parmW arg1
  167. ; cBegin
  168. ; movzx, eax, arg1
  169. ; push eax
  170. ; call far ptr _Api OR Api32 (decorates the names)
  171. ;
  172. ; if necessary checks the callservercondtion
  173. ; resets the callservercondition
  174. ; push arg1
  175. ; call WOWApi ; the actual thunk to wow32/server
  176. ; @@:
  177. ; endif
  178. ;
  179. ; if exists, includes code in apispecificcode_api
  180. ; endif
  181. ; cEnd
  182. ; sEnd CODE
  183. ;
  184. ; - nanduri
  185. ;--------------------------------------------------------------------------
  186. USER16CLIENTTHUNK macro Iapi, api, argtypeslist, returntype, api32, apispecificcode, callserver
  187. ;*** declare api
  188. ;
  189. index = 0
  190. IRP argtype, <argtypeslist>
  191. index = index + 1
  192. ENDM
  193. IFB <api32>
  194. CALLORDECLARE <externFP>, _&api, %(index*4)
  195. ELSE
  196. CALLORDECLARE <externFP>, _&api32, %(index*4)
  197. ENDIF
  198. sBegin CODE ; _&api
  199. ;*** create thunk to wow32
  200. ;
  201. IFNB <callserver>
  202. FUN_WOW&api equ FUN_&api
  203. DUserThunk WOW&api, %(size api&16)
  204. ENDIF
  205. ;*** create thea Api label
  206. ;
  207. IFNB <api>
  208. IFIDNI <Iapi>, <DUSERTHUNK>
  209. cProc &api, <PUBLIC, FAR, PASCAL>, <ds>
  210. ELSE
  211. cProc I&api, <PUBLIC, FAR, PASCAL>, <ds>
  212. ENDIF
  213. ENDIF
  214. ;*** declare args
  215. ;
  216. nargcount = 0
  217. IRP argtype, <argtypeslist>
  218. nargcount = nargcount + 1
  219. IFIDNI <argtype>, <WORD>
  220. genparam W, arg%(nargcount)
  221. ENDIF
  222. IFIDNI <argtype>, <INT>
  223. genparam W, arg%(nargcount)
  224. ENDIF
  225. IFIDNI <argtype>, <SHORT>
  226. genparam W, arg%(nargcount)
  227. ENDIF
  228. IFIDNI <argtype>, <DWORD>
  229. genparam D, arg%(nargcount)
  230. ENDIF
  231. IFIDNI <argtype>, <LONG>
  232. genparam D, arg%(nargcount)
  233. ENDIF
  234. IFIDNI <argtype>, <ULONG>
  235. genparam D, arg%(nargcount)
  236. ENDIF
  237. IFIDNI <argtype>, <PSZ>
  238. genparam D, arg%(nargcount)
  239. ENDIF
  240. IFIDNI <argtype>, <NONOPTPSZ>
  241. genparam D, arg%(nargcount)
  242. ENDIF
  243. IFIDNI <argtype>, <HWND>
  244. genparam W, arg%(nargcount)
  245. ENDIF
  246. IFIDNI <argtype>, <HHOOK>
  247. genparam D, arg%(nargcount)
  248. ENDIF
  249. ENDM
  250. ;*** begin body
  251. ;
  252. cBegin
  253. ;*** set 32bit registers
  254. ;
  255. SETFLATDSANDFS
  256. ;*** push args in reverse
  257. ;
  258. FailCall = 0
  259. argtopush = nargcount
  260. REPT nargcount
  261. inputargindex = 0
  262. IRP argtype, <argtypeslist>
  263. inputargindex = inputargindex + 1
  264. IFE argtopush - inputargindex
  265. IFIDNI <argtype>, <WORD>
  266. pushWORD_DWORD arg%argtopush
  267. ENDIF
  268. IFIDNI <argtype>, <INT>
  269. pushINT_LONG arg%argtopush
  270. ENDIF
  271. IFIDNI <argtype>, <SHORT>
  272. pushINT_LONG arg%argtopush
  273. ENDIF
  274. IFIDNI <argtype>, <DWORD>
  275. pushDWORD_DWORD arg%argtopush
  276. ENDIF
  277. IFIDNI <argtype>, <LONG>
  278. pushDWORD_DWORD arg%argtopush
  279. ENDIF
  280. IFIDNI <argtype>, <ULONG>
  281. pushDWORD_DWORD arg%argtopush
  282. ENDIF
  283. IFIDNI <argtype>, <PSZ>
  284. pushPSZ_DWORD arg%argtopush
  285. ENDIF
  286. IFIDNI <argtype>, <NONOPTPSZ>
  287. FailCall = argtopush ; fails call if null
  288. pushPSZ_DWORD arg%argtopush, &api, %argtopush
  289. ENDIF
  290. IFIDNI <argtype>, <HWND>
  291. pushINT_LONG arg%argtopush
  292. ENDIF
  293. IFIDNI <argtype>, <HHOOK>
  294. pushHHOOK_DWORD arg%argtopush
  295. ENDIF
  296. ENDIF
  297. ENDM
  298. argtopush = argtopush - 1
  299. ENDM
  300. ;*** called user32/client api
  301. ;
  302. IFB <api32>
  303. CALLORDECLARE <call>, _&api, %(nargcount*4)
  304. ELSE
  305. CALLORDECLARE <call>, _&api32, %(nargcount*4)
  306. ENDIF
  307. ;*** check if we ever need to call server
  308. ;*** calls the real wow thunk
  309. IFNB <callserver>
  310. TESTCALLSERVERCONDITION
  311. jz @F
  312. CLEARCALLSERVERCONDITION
  313. index = 0;
  314. IRP argtype, <argtypeslist>
  315. index = index + 1
  316. pushARG16 arg%index
  317. ENDM
  318. call WOW&api
  319. @@:
  320. ENDIF
  321. ;*** check for any api specific compatibility code to execute
  322. ;
  323. IFNB <apispecificcode>
  324. APISPECIFICCODE_&api
  325. ENDIF
  326. IF FailCall
  327. FailCall_&api:
  328. ENDIF
  329. IFNB <returntype>
  330. IRP argtype, <dword, long, ulong>
  331. IFIDNI <returntype>, <argtype>
  332. mov edx, eax
  333. shr edx, 16
  334. EXITM
  335. ENDIF
  336. ENDM
  337. IFIDNI <returntype>, <boolzero>
  338. xor ax, ax
  339. ENDIF
  340. ENDIF
  341. ifdef DEBUG
  342. ;LOGARGS &api
  343. endif
  344. cEnd
  345. ; end body
  346. sEnd CODE ; _&api
  347. endm
  348. endif ; PMODE32
  349. assumes CS,CODE
  350. assumes DS,DATA
  351. assumes ES,NOTHING
  352. ;;;;;;;;;;sBegin CODE ; macro will generate this
  353. APISPECIFICCODE_GETCLIENTRECT macro
  354. xor eax, eax
  355. endm
  356. APISPECIFICCODE_GETKEYSTATE macro
  357. mov cl, ah
  358. and cl, 080h
  359. or al, cl
  360. endm
  361. APISPECIFICCODE_GETWINDOWRECT macro
  362. xor eax, eax
  363. endm
  364. ; The following call is only for a dBase for Windows 5.0 bug. Notice however, that this
  365. ; means that the internal KERNEL api WowSetCompatHandle will be called for every
  366. ; single invocation of GetDlgItem, no matter what app is running. This is bad, but
  367. ; on X86 platforms we don't transition to WOW32, and the cost of testing for it
  368. ; is just about as expensive as just saving it. Still, this should be removed as
  369. ; soon as we are convinced that the dBase bug has been fixed. -NeilSa
  370. APISPECIFICCODE_GETDLGITEM macro
  371. push ax
  372. call WowSetCompatHandle
  373. endm
  374. public _wow16gpsi
  375. public _wow16CsrFlag
  376. public _wow16gHighestUserAddress
  377. sBegin CODE
  378. _wow16gpsi DD 0
  379. _wow16CsrFlag DD 0
  380. _wow16gHighestUserAddress DD 0
  381. sEnd CODE
  382. ; the following may end up calling wow32
  383. USER16CLIENTTHUNK UserThunk, DEFHOOKPROC, <int, word, dword, hhook>, dword, WOW16DefHookProc,,srvcond
  384. USER16CLIENTTHUNK UserThunk, ENABLEMENUITEM, <hwnd, word, word>, word,,,srvcond
  385. USER16CLIENTTHUNK DUserThunk, GETKEYSTATE, <int>, int,, compatcode, srvcond
  386. USER16CLIENTTHUNK UserThunk, GETKEYBOARDSTATE, <nonoptpsz>, boolzero,,,srvcond
  387. ; the following are all thunked locally
  388. USER16CLIENTTHUNK UserThunk, CLIENTTOSCREEN, <hwnd, psz>,boolzero
  389. USER16CLIENTTHUNK UserThunk, GETCLASSNAME, <hwnd, psz, word>, word, GETCLASSNAMEA
  390. USER16CLIENTTHUNK UserThunk, GETCLIENTRECT, <hwnd, psz>, bool,,compatcode
  391. USER16CLIENTTHUNK UserThunk, GETCURSORPOS, <psz>, boolzero
  392. USER16CLIENTTHUNK DUserThunk, GETDESKTOPHWND, <>, hwnd, GETDESKTOPWINDOW
  393. USER16CLIENTTHUNK DUserThunk, GETDESKTOPWINDOW, <>, hwnd
  394. USER16CLIENTTHUNK UserThunk, GETDLGITEM, <hwnd, word>, hwnd,,compatcode
  395. USER16CLIENTTHUNK UserThunk, GETMENU, <hwnd>, hmenu
  396. USER16CLIENTTHUNK UserThunk, GETMENUITEMCOUNT, <hwnd>, int
  397. USER16CLIENTTHUNK UserThunk, GETMENUITEMID, <hwnd, int>, uint
  398. USER16CLIENTTHUNK UserThunk, GETMENUSTATE, <hwnd, word, word>, uint
  399. USER16CLIENTTHUNK DUserThunk, GETNEXTWINDOW, <hwnd, word>, hwnd, GETWINDOW
  400. USER16CLIENTTHUNK UserThunk, GETPARENT, <hwnd>, hwnd
  401. USER16CLIENTTHUNK UserThunk, GETSUBMENU, <hwnd, int>, hmenu
  402. USER16CLIENTTHUNK UserThunk, GETSYSCOLOR, <int>, dword
  403. USER16CLIENTTHUNK UserThunk, GETSYSTEMMETRICS, <int>, int
  404. USER16CLIENTTHUNK UserThunk, GETTOPWINDOW, <hwnd>, hwnd
  405. USER16CLIENTTHUNK UserThunk, GETWINDOW, <hwnd, word>, hwnd
  406. USER16CLIENTTHUNK UserThunk, GETWINDOWRECT, <hwnd, psz>, bool,,compatcode
  407. USER16CLIENTTHUNK DUserThunk, ISWINDOW, <hwnd>, bool
  408. USER16CLIENTTHUNK UserThunk, SCREENTOCLIENT, <hwnd, psz>, boolzero
  409. ifdef DEBUG
  410. USER16CLIENTTHUNK UserThunk, ISCHILD, <hwnd, hwnd>, bool
  411. USER16CLIENTTHUNK UserThunk, ISICONIC, <hwnd>, bool
  412. USER16CLIENTTHUNK UserThunk, ISWINDOWENABLED, <hwnd>, bool
  413. USER16CLIENTTHUNK UserThunk, ISWINDOWVISIBLE, <hwnd>, bool
  414. USER16CLIENTTHUNK UserThunk, ISZOOMED, <hwnd>, bool
  415. else
  416. USER16CLIENTTHUNK DUserThunk, ISCHILD, <hwnd, hwnd>, bool
  417. USER16CLIENTTHUNK DUserThunk, ISICONIC, <hwnd>, bool
  418. USER16CLIENTTHUNK DUserThunk, ISWINDOWENABLED, <hwnd>, bool
  419. USER16CLIENTTHUNK DUserThunk, ISWINDOWVISIBLE, <hwnd>, bool
  420. USER16CLIENTTHUNK DUserThunk, ISZOOMED, <hwnd>, bool
  421. endif
  422. ;;;;;;;;;sEnd CODE ; macro will generate this
  423. sBegin CODE
  424. ifndef PMODE32
  425. DUserThunk GETTICKCOUNT, 0
  426. DUserThunk GETCURRENTTIME, 0
  427. else
  428. labelFP <PUBLIC, GETTICKCOUNT>
  429. labelFP <PUBLIC, GETCURRENTTIME>
  430. ; the TickCount is accessible from client address space.
  431. ; refer sdk\inc\ntexapi.h
  432. ; - nanduri
  433. .386p
  434. ; set 32bit ds
  435. push ds
  436. mov ax, FLATDS
  437. mov ds, ax
  438. ; from sdk\inc\ntexapi.h NtGetTickCount - equivalent code
  439. mov edx, MM_SHARED_USER_DATA_VA
  440. mov eax, [edx].UsTickCountLow
  441. mul dword ptr [edx].UsTickCountMultiplier
  442. shrd eax,edx,24
  443. mov edx, eax
  444. shr edx, 010h
  445. and ax, NOT GRAINYTIC_RES ; round off to lower 64 boundary
  446. ;this is a cheap implemention of WOWCF_GRAINYTICS flag
  447. pop ds
  448. retf
  449. .286p
  450. endif
  451. sEnd CODE
  452. end