Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1456 lines
42 KiB

  1. TITLE WOW16CAL.ASM
  2. PAGE ,132
  3. ;
  4. ; WOW v1.0
  5. ;
  6. ; Copyright (c) 1991, Microsoft Corporation
  7. ;
  8. ; WOW16CAL.ASM
  9. ; Thunk router in 16-bit space to route Windows API calls to WOW32
  10. ;
  11. ; History:
  12. ; 25-Jan-1991 Jeff Parsons (jeffpar) Created.
  13. ; 24-Apr-91 Matt Felton (mattfe) Incorporated into Kernel
  14. ; 29-May-91 Matt Felton (mattfe) Added Multi-Tasking
  15. ; 30-Apr-1992 Mike Tricker (MikeTri) Added MultiMedia callbacks
  16. ;
  17. ; .xlist
  18. include kernel.inc
  19. include tdb.inc
  20. include dbgsvc.inc
  21. include wow.inc
  22. include dpmi.inc
  23. include cmacros.inc
  24. ; include NEW_SEG1 struc used in GetProcModule
  25. include newexe.inc
  26. .list
  27. HACK16 equ 1 ;enable hacks
  28. .286p
  29. Entry macro name
  30. ;align 16
  31. public name
  32. name&:
  33. endm
  34. externFP SETCURSORICONFLAG
  35. externFP SETDDEHANDLEFLAG
  36. externFP LOCALALLOC
  37. externFP LOCALREALLOC
  38. externFP LOCALLOCK
  39. externFP LOCALHANDLE
  40. externFP LOCALUNLOCK
  41. externFP LOCALSIZE
  42. externFP LOCALFREE
  43. externFP LOCALINIT
  44. externFP LOCKSEGMENT
  45. externFP UNLOCKSEGMENT
  46. externFP GLOBALALLOC
  47. externFP GLOBALLOCK
  48. externFP GLOBALHANDLE
  49. externFP GLOBALUNLOCK
  50. externFP GLOBALSIZE
  51. externFP GLOBALFREE
  52. externFP FINDRESOURCE
  53. externFP LOADRESOURCE
  54. externFP FREERESOURCE
  55. externFP LOCKRESOURCE
  56. externFP SIZEOFRESOURCE
  57. externFP Int21Handler
  58. externFP IsBadReadPtr
  59. externFP GetSelectorLimit
  60. externFP GetExpWinVer
  61. externNP SwitchTask
  62. externNP WOW16TaskStarted
  63. externFP GetExePtr
  64. externFP GetModuleUsage
  65. externFP WOWGetFastAddress
  66. externFP WOWGetFastCbRetAddress
  67. externFP WowGetFlatAddressArray
  68. externFP WOWNotifyWOW32
  69. externFP GETMODULEHANDLE
  70. externFP GETPROCADDRESS
  71. externFP PrestoChangoSelector
  72. externFP GetModuleFileName
  73. externFP WinExec
  74. externW gdtdsc
  75. externW pLocalHeap
  76. externW hUser
  77. externNP SetOwner
  78. externFP WowCheckUserGdi
  79. externFP GetExePtr
  80. externFP FatalExit
  81. sBegin NRESCODE
  82. externFP get_sel_flags
  83. externFP set_sel_for_dib
  84. externFP RestoreDib
  85. sEnd NRESCODE
  86. DataBegin
  87. externW wCurTaskSS
  88. externW wCurTaskBP
  89. externW Win_PDB ;MikeTri - extracting DOS PDB and SFT
  90. externD pFileTable
  91. externB fExitOnLastApp
  92. externD plstrcmp
  93. externW THHOOK
  94. externD FastBop
  95. externD FastWOW
  96. externW FastWOWCS
  97. externD FastWOWCbRet
  98. externW FastWOWCbRetCS
  99. externD FlatAddressArray
  100. externW WOWFastBopping
  101. externW curTDB
  102. externW cur_drive_owner
  103. externW LockTDB
  104. externB num_tasks
  105. externW DebugWOW
  106. externW topPDB
  107. externW TraceOff
  108. externD pDosWowData
  109. ;ifdef FE_SB
  110. ;externW hModNotepad
  111. ;endif ; FE_SB
  112. UserModuleName DB 'USER.EXE', 0
  113. DataEnd
  114. sBegin CODE
  115. assumes CS,CODE
  116. assumes DS,NOTHING
  117. assumes ES,NOTHING
  118. public apfnWOW16Func ;make public to help debugging
  119. apfnWOW16Func dw WOW16Return ;order MUST match RET_* (wow.h)
  120. dw WOW16DebugReturn
  121. dw WOW16Debug
  122. dw WOW16WndProc
  123. dw WOW16EnumFontProc
  124. dw WOW16EnumWindowProc
  125. dw WOW16LocalAlloc
  126. dw WOW16LocalReAlloc
  127. dw WOW16LocalLock
  128. dw WOW16LocalUnlock
  129. dw WOW16LocalSize
  130. dw WOW16LocalFree
  131. dw WOW16GlobalAllocLock
  132. dw WOW16GlobalLock
  133. dw WOW16GlobalUnlock
  134. dw WOW16GlobalUnlockFree
  135. dw WOW16FindResource
  136. dw WOW16LoadResource
  137. dw WOW16FreeResource
  138. dw WOW16LockResource
  139. dw WOW16GlobalUnlock ;there is no UnlockResource
  140. dw WOW16SizeofResource
  141. dw WOW16LockSegment
  142. dw WOW16UnlockSegment
  143. dw WOW16EnumMetaFileProc
  144. dw WOW16TaskStartedTmp ; in Tasking.asm
  145. dw WOW16HookProc
  146. dw WOW16SubClassProc
  147. dw WOW16LineDDAProc
  148. dw WOW16GrayStringProc
  149. dw WOW16ForceTaskExit
  150. dw WOW16SetCurDir
  151. dw WOW16EnumObjProc
  152. dw WOW16SetCursorIconFlag
  153. dw WOW16SetAbortProc
  154. dw WOW16EnumPropsProc
  155. dw WOW16ForceSegmentFault
  156. dw WOW16lstrcmp
  157. dw 0 ;FREE
  158. dw 0 ;FREE
  159. dw 0 ;FREE
  160. dw 0 ;FREE
  161. dw WOW16GetExePtr
  162. dw 0 ; WOW16GetModuleUsage removed
  163. dw WOW16ForceTaskFault
  164. dw WOW16GetExpWinVer
  165. dw WOW16GetCurDir
  166. dw WOW16GetDosPDB
  167. dw WOW16GetDosSFT
  168. dw WOW16ForegroundIdle
  169. dw WOW16WinsockBlockHook
  170. dw WOW16SetDdeHandleFlag
  171. dw WOW16ChangeSelector
  172. dw WOW16GetModuleFilename
  173. dw WOW16WordBreakProc
  174. dw WOW16WinExec
  175. dw WOW16WOWCallback16
  176. dw WOW16GetDibSize
  177. dw WOW16GetDibFlags
  178. dw WOW16SetDibSel
  179. dw WOW16FreeDibSel
  180. ;ifdef FE_SB
  181. ; dw WOW16SetFNotepad ; for Lotus Freelance for Win
  182. ;endif ; FE_SB
  183. functableend equ $
  184. ; the aRets table looks like this: ...retf, ...retf 2, ...retf 4, ...
  185. CRETENTRIES equ 020h
  186. ; generate the retf n codetable
  187. bytes = 0
  188. REPT CRETENTRIES
  189. align 8
  190. IFE bytes
  191. aRets:
  192. ENDIF
  193. pop bx ;restore app BX
  194. pop bp
  195. add sp, 0ah ;pop thunk ret address, wCallID/lpfn, wArgs
  196. retf bytes
  197. bytes = bytes + 2
  198. ENDM
  199. align 8
  200. rettableend equ $
  201. RETFCODESIZE equ (rettableend - aRets) / CRETENTRIES
  202. .errnz ((rettableend - aRets) AND 01h) ; complain if odd
  203. .erre (RETFCODESIZE EQ 08h)
  204. ; if the size is not 8 bytes need to
  205. ; change the code that indexes 'aRets'
  206. ;----------------------------------------------------------------------------
  207. ; these comments are a result of hard labour (so called 'fruits'
  208. ; of hard labour)
  209. ;
  210. ; 1. If you make a change in VDMFRAME or similar such change, make sure
  211. ; tasking.asm is in sync. pay attention to the labels wow16doneboot,
  212. ; wow16taskstarted and the resetting of vf_wES (all in tasking.asm)
  213. ;
  214. ; 2. The general purpose registers es, bx, cx which are saved around the
  215. ; the api thunks. LATER these have to be removed with care and caution.
  216. ; If you just remove the push/pop of these, kernel31 won't boot.
  217. ; These registers will have to be saved around certain calls in krnl286/386
  218. ; for it to boot.
  219. ;
  220. ; - nanduri ramakrishna
  221. ;
  222. ;-----------------------------------------------------------------------------
  223. ;-----------------------------------------------------------------------------
  224. ; NOTES:
  225. ;
  226. ; the frame at time of bop is of type VDMFRAME
  227. ; the frame at the time of a callback is CBVDMFRAME.
  228. ; VDMFRAME and CBVDMFRAME share the first few fields (the order is important)
  229. ; but the structures don't overlap.
  230. ;
  231. ; ie stack looks like this
  232. ;
  233. ; ss:sp = VDMFRAME
  234. ; ... BOP ....
  235. ; if return from BOP:
  236. ; ss:sp = VDMFRAME
  237. ; if from callback16:
  238. ; ss:sp = CBVDMFRAME
  239. ; .....callback function...
  240. ; - nanduri ramakrishna
  241. ;-----------------------------------------------------------------------------
  242. assumes ds, nothing
  243. assumes es, nothing
  244. align 16
  245. cProc WOW16Call,<PUBLIC,FAR>
  246. ; parmW wArgs ; # paramater bytes pushed for this API
  247. ; parmW wCallID
  248. ; note that 'bp' of api thunk and callback differ
  249. pFrame equ [bp-vf_wBP]
  250. wAppBX equ [pFrame].vf_wBX
  251. wApiRetID equ [pFrame].vf_wRetID
  252. wAX equ [pFrame].vf_wAX
  253. wArgs equ [pFrame].vf_cbArgs
  254. ; for callback16
  255. pCBFrame equ [bp-cvf_Parm16];
  256. vpfnProc equ [pCBFrame].cvf_vpfnProc
  257. hInst equ [pCBFrame+cvf_Parm16].wp_hInst
  258. hwnd equ [pCBFrame+cvf_Parm16].wp_hwnd
  259. wMsg equ [pCBFrame+cvf_Parm16].wp_wMsg
  260. wParam equ [pCBFrame+cvf_Parm16].wp_wParam
  261. lParam equ [pCBFrame+cvf_Parm16].wp_lParam
  262. vpfnWndProc equ [di-cvf_Parm16].cvf_vpfnProc
  263. lpstr1 equ [pCBFrame+cvf_Parm16].lstrcmpParms.lstrcmp16_lpstr1
  264. lpstr2 equ [pCBFrame+cvf_Parm16].lstrcmpParms.lstrcmp16_lpstr2
  265. cbackAX equ [pCBFrame].cvf_wAX ;
  266. cbackDX equ [pCBFrame].cvf_wDX
  267. wGenUse1 equ [pCBFrame].cvf_wGenUse1
  268. wGenUse2 equ [pCBFrame].cvf_wGenUse2
  269. vfSP equ [pCBFrame].cvf_vpStack ; lo word is sp = ptr to vdmframe
  270. ; The stack frame here is defined in wow.h make sure they match
  271. ; the order is very important.
  272. cBegin nogen
  273. wc_set_vdmframe:
  274. push bp
  275. mov bp, sp ; standard frame
  276. push bx ; REMOVE LATER APPs BX
  277. push es ; REMOVE LATER
  278. push cx ; REMOVE LATER
  279. .386
  280. ; %OUT building 386
  281. push fs
  282. push gs
  283. .286
  284. push ds
  285. sub sp, 4 ; room for api dword return value
  286. push si ; standard regs
  287. push di
  288. WOW16ApiCall:
  289. push bp
  290. push RET_RETURN ;push default wRetID (do not move see tasking.asm)
  291. SetKernelDS ds
  292. push [curTDB] ;save current 16bit task handle (see tasking.asm)
  293. mov di,ss
  294. mov [wCurTaskSS],di ;save current task SS
  295. mov [wCurTaskBP],bp ;save current task BP
  296. ; We don't want to allow debuggers to trace into 32 bit land, since they
  297. ; will get lost.
  298. mov TraceOff,1h
  299. test [WOWFastBopping], 0ffffh
  300. jz WOW16SlowVector
  301. WOW16FastVector:
  302. .386
  303. call fword ptr [FastWOW]
  304. .286
  305. jmp short WOW16CallContinue
  306. public WOW16SlowVector
  307. Entry WOW16SlowVector
  308. BOP BOP_WOW
  309. public WOW16CallContinue
  310. WOW16CallContinue: ; don't move this label! see comment below
  311. SetKernelDS ds
  312. xor ax,ax
  313. xchg TraceOff,ax
  314. test ax,2h ; Turn Tracing Back on ?
  315. jnz turn_on_trace_bit
  316. W16C_010:
  317. ; Check for Task Switch
  318. pop ax ; retrieve current task ID
  319. cmp ax, [curTDB] ; Task Switch ?
  320. jnz jmpSwitchTask ; Yes -> Perform Task Switch
  321. public WOW16CallNewTaskRet ; from tasking.asm
  322. WOW16CallNewTaskRet:
  323. pop bx ;retrieve wRetID
  324. pop bp ;localbp
  325. cmp bx, RET_RETURN
  326. jnz WOW16_From_CallBack16
  327. public WOW16Return
  328. WOW16Return:
  329. ; we don't want to return to the thunk, that's just going to
  330. ; do a RETF n where n is the # of parameters to the API.
  331. ; doing this takes about half the time of a RETF on a 486
  332. ; according to the clock counts in the book. but RETF also flushes
  333. ; the instruction prefetch queue, and we're touching one less page
  334. ; (probably a TLB miss if we're coming back from a call with a long
  335. ; code path).
  336. wc_restore_regs:
  337. pop di
  338. pop si
  339. pop ax ;
  340. pop dx
  341. pop ds
  342. .386
  343. pop gs
  344. pop fs
  345. .286
  346. pop cx ; REMOVE LATER
  347. pop es ; REMOVE LATER
  348. mov bx,wArgs ; get the # of bytes this API took
  349. if KDEBUG
  350. or bx, bx
  351. jz @F
  352. test bx, 01h
  353. jz @F
  354. int 3 ; error. odd #bytes to pop
  355. @@:
  356. cmp bx, CRETENTRIES * 2
  357. jl @F
  358. int 3 ; error. outside aRets tablerange
  359. @@:
  360. endif
  361. shl bx, 2 ; convert it to offset into aRets table
  362. add bx, codeoffset aRets
  363. jmp bx ; dispatch to the right RETF n
  364. ;
  365. ; If a debugger was tracing the app then reenable on the 16 bit side again
  366. ;
  367. turn_on_trace_bit:
  368. pushf
  369. pop ax
  370. or ax,FLG_TRAP
  371. push ax
  372. popf
  373. jmps W16C_010
  374. public WOW16_From_CallBack16
  375. WOW16_From_CallBack16: ; exception RET_DEBUGRETURN and RET_TASKSTARTED
  376. mov si, bp ; save bp, dont push on stack
  377. mov bp, sp ; for convenience.
  378. mov ax, ss
  379. mov es, ax
  380. mov ds, ax
  381. mov ax, cbackAX ; for prolog initialization
  382. add bx,bx
  383. jmp apfnWOW16Func[bx] ;route to appropriate function handler
  384. public WOW16DebugReturn
  385. Entry WOW16DebugReturn
  386. ; undo the 'callback' munging
  387. mov bp, si
  388. int 3 ;that's all folks
  389. jmps WOW16Return
  390. jmpSwitchTask:
  391. jmp SwitchTask ; Go perform a Task Switch
  392. public WOW16TaskStartedTmp
  393. Entry WOW16TaskStartedTmp
  394. ; undo the 'callback' munging
  395. mov bp, si
  396. pop di
  397. pop si
  398. pop ax ;
  399. pop dx
  400. pop ds
  401. .386
  402. pop gs
  403. pop fs
  404. .286
  405. pop cx ; REMOVE LATER
  406. pop es ; REMOVE LATER
  407. pop bx ; pop bx ; REMOVE LATER;
  408. mov wApiRetID, RET_RETURN
  409. jmp WOW16TaskStarted
  410. ;
  411. ; Call Back Routines
  412. ; On entry, SS:SP points to PARM16 structure
  413. ; Assumes PARM16 is followed by vpfn
  414. ;
  415. public WOW16WOWCallback16
  416. Entry WOW16WOWCallback16 ; 32-bit generic callback
  417. call [vpfnProc] ; call the target proc
  418. mov si, [wGenUse1] ; si = cbArgs
  419. sub sp, si ; undo effect of "RET cbArgs"
  420. jmp WOW16Done
  421. public WOW16WndProc
  422. Entry WOW16WndProc
  423. ; don't expect si and di to be saved by the callback function - so save the
  424. ; critical info elsewhere like on stack.
  425. ; we set 'si' to 'hwnd'. this fixes a bug in QuickCase (qcasew.exe) where
  426. ; options.tools.add doesn't bring up a dialog box.
  427. ;
  428. mov cx,hwnd ;for later use
  429. mov di,bp ;MSAccess debug version walks BP chain. they're
  430. mov bp,si ; testing it for us, let's make it easier for them.
  431. mov wAX,di ;save current bp in vdmframe.wAX - temporary
  432. ;note:
  433. ; current 'bp (ie di) = 'sp' ,also vdmFrame can be
  434. ; accessed with the new 'bp' (ie 'si').
  435. mov si,cx ;si has hwnd
  436. call [vpfnWndProc] ;call the window proc (AX already set)
  437. mov bp,wAX ;restore pre-callback bp
  438. mov sp,bp ;restore pre-callback sp
  439. jmp WOW16Done ;call back to WOW32
  440. public WOW16EnumFontProc
  441. Entry WOW16EnumFontProc
  442. call [vpfnProc] ;call the font proc
  443. ifdef FE_SB ; HACK for Golf , MS-GolfJ has ( retf 0x34 )!!!
  444. mov sp,bp
  445. else
  446. sub sp,size PARMEFP ;undo the effect of the proc's RET 0Eh
  447. endif ;FE_SB
  448. jmp WOW16Done ;call back to WOW32
  449. public WOW16EnumObjProc
  450. Entry WOW16EnumObjProc
  451. call [vpfnProc] ;call the obj proc
  452. sub sp,size PARMEOP ;undo the effect of the proc's RET 0Eh
  453. jmp WOW16Done ;call back to WOW32
  454. public WOW16EnumWindowProc
  455. Entry WOW16EnumWindowProc
  456. call [vpfnProc] ;call the font proc
  457. sub sp,size PARMEWP ;undo the effect of the proc's RET 06h
  458. jmp WOW16Done ;call back to WOW32
  459. public WOW16LineDDAProc
  460. Entry WOW16LineDDAProc
  461. call [vpfnProc] ;call the Line DDA proc
  462. sub sp,size PARMDDA ;undo the effect of the proc's RET 0Eh
  463. jmp WOW16Done ;call back to WOW32
  464. public WOW16GrayStringProc
  465. Entry WOW16GrayStringProc
  466. call [vpfnProc] ;call the Graystring proc
  467. sub sp,size PARMGST ;undo the effect of the proc's RET 0Eh
  468. jmp WOW16Done ;call back to WOW32
  469. public WOW16EnumPropsProc
  470. Entry WOW16EnumPropsProc
  471. call [vpfnProc] ;call the obj proc
  472. sub sp,size PARMEPP ;undo the effect of the proc's RET
  473. jmp WOW16Done ;call back to WOW32
  474. public WOW16WordBreakProc
  475. Entry WOW16WordBreakProc
  476. call [vpfnProc] ;call the wordbreak proc
  477. sub sp,size PARMWBP ;undo the effect of the proc's RET
  478. jmp WOW16Done ;call back to WOW32
  479. if 0
  480. ;
  481. ; MultiMedia callbacks - MikeTri 30-Apr-1992
  482. ;
  483. Entry WOW16MidiInFunc
  484. call [vpfnProc] ;call the MidiIn proc
  485. sub sp,size PARMMIF ;undo the effect of the proc's RET 12h
  486. jmp WOW16Done ;call back to WOW32
  487. Entry WOW16MidiOutFunc
  488. call [vpfnProc] ;call the MidiOut proc
  489. sub sp,size PARMMOF ;undo the effect of the proc's RET 12h
  490. jmp WOW16Done ;call back to WOW32
  491. Entry WOW16IOProc
  492. call [vpfnProc] ;call the MMIO proc
  493. sub sp,size PARMIOP ;undo the effect of the proc's RET 0Eh
  494. jmp WOW16Done ;call back to WOW32
  495. Entry WOW16TimeFunc
  496. call [vpfnProc] ;call the Time proc
  497. sub sp,size PARMTIF ;undo the effect of the proc's RET 10h
  498. jmp WOW16Done ;call back to WOW32
  499. Entry WOW16WaveInFunc
  500. call [vpfnProc] ;call the WaveIn proc
  501. sub sp,size PARMWIF ;undo the effect of the proc's RET 12h
  502. jmp WOW16Done ;call back to WOW32
  503. Entry WOW16WaveOutFunc
  504. call [vpfnProc] ;call the WaveOut proc
  505. sub sp,size PARMWOF ;undo the effect of the proc's RET 12h
  506. jmp WOW16Done ;call back to WOW32
  507. endif
  508. Entry WOW16LocalAlloc
  509. mov ax,wMsg ; set up DS with hInstance
  510. mov ds,ax
  511. cmp ds:[pLocalHeap], 0 ; already have a local heap in this DS?
  512. jnz @f ; yes
  513. ; we need to LocalInit this segment
  514. ; note: Win3.1 doesn't check return codes on GlobalSize, LocalInit
  515. push ds
  516. call far ptr GLOBALSIZE
  517. sub ax, 64
  518. push ds
  519. push 0
  520. push ax
  521. call far ptr LOCALINIT
  522. push ds
  523. call far ptr UNLOCKSEGMENT
  524. @@:
  525. push wParam ;push wFlags
  526. push lParam.lo ;push wBytes
  527. call far ptr LOCALALLOC ;get hmem in AX
  528. mov dx,ds ; return DS in hiword of handle
  529. jmp WOW16Done ;
  530. Entry WOW16LocalReAlloc
  531. mov ax,lParam.hi ; set up DS with value from alloc
  532. mov ds,ax
  533. push lParam.lo ;push hMem
  534. push wMsg ;push wBytes
  535. push wParam ;push wFlags
  536. call far ptr LOCALREALLOC;get hmem in AX
  537. mov dx,ds ;hiword of handle=DS
  538. jmp WOW16Done
  539. Entry WOW16LocalLock
  540. if 0
  541. ; HACK32 remove this!
  542. mov ax,lParam.hi ; set up DS with value from alloc
  543. mov ds,ax
  544. push lParam.lo ;push hMem
  545. call far ptr LOCALLOCK ;
  546. sub dx,dx ;
  547. or ax,ax ;
  548. jz short lalock_done ;
  549. IFDEF HACK16
  550. push ax
  551. push -1
  552. call far ptr LOCKSEGMENT
  553. pop ax
  554. ENDIF
  555. mov dx,ds ;if success, return full address in DX:AX
  556. lalock_done: ;
  557. endif
  558. jmp WOW16Done ;
  559. Entry WOW16LocalUnlock
  560. if 0
  561. ; HACK32 remove this!
  562. mov ax,lParam.hi ; set up DS with value from alloc
  563. mov ds,ax
  564. push lParam.lo ;push hMem
  565. call far ptr LOCALUNLOCK ;
  566. or ax,ax ;
  567. jnz short lufree_done ;
  568. IFDEF HACK16
  569. push -1
  570. call far ptr UNLOCKSEGMENT
  571. sub ax,ax ;
  572. ENDIF
  573. lufree_done: ;
  574. cwd ;
  575. endif
  576. jmp WOW16Done ;
  577. Entry WOW16LocalSize
  578. mov ax,lParam.hi ; set up DS with value from alloc
  579. mov ds,ax
  580. push lParam.lo ;push hMem
  581. call far ptr LOCALSIZE ;
  582. sub dx,dx
  583. jmp WOW16Done
  584. Entry WOW16LocalFree
  585. push es ; IsBadReadPtr can trash ES and BX
  586. push bx
  587. mov ax,lParam.hi ; get selector of current local heap
  588. push ax ; set up for call to IsBadReadPtr
  589. push 0
  590. push 1
  591. call far ptr IsBadReadPtr ; is selector still valid?
  592. pop bx
  593. pop es
  594. or ax,ax
  595. jnz wlf_done ; ax != 0 -> nope!
  596. mov ax,lParam.hi ; set up DS with value from alloc
  597. mov ds,ax
  598. push lParam.lo ;push hMem
  599. call far ptr LOCALFREE ;
  600. wlf_done:
  601. jmp WOW16Done ;
  602. Entry WOW16GlobalAllocLock
  603. push wParam ;push wFlags
  604. push lParam.hi ;push dwBytes
  605. push lParam.lo ;
  606. call far ptr GLOBALALLOC ;get hmem in AX
  607. sub dx,dx ;
  608. or ax,ax ;
  609. jz short galock_done ;
  610. push ax ;save hmem
  611. push ax ;push hmem
  612. call far ptr GLOBALLOCK ;get seg:off in DX:AX
  613. pop bx ;recover hmem in BX
  614. galock_done: ;
  615. mov wGenUse1, bx
  616. jmp WOW16Done ;
  617. Entry WOW16GlobalLock
  618. push wParam ;push hMem
  619. call far ptr GLOBALLOCK ;
  620. push ax ;save return value
  621. push dx ;
  622. or ax,dx
  623. jz glock_exit
  624. push wParam ;push hMem
  625. call far ptr GLOBALSIZE ;
  626. glock_exit:
  627. mov wGenUse2,ax ;save size
  628. mov wGenUse1,dx ;
  629. pop dx ;
  630. pop ax ;
  631. jmp WOW16Done ;
  632. Entry WOW16GlobalUnlock
  633. push wParam ;push hMem
  634. call far ptr GLOBALUNLOCK;
  635. cmp ax,1 ;
  636. sbb ax,ax ;
  637. cwd ;make return code a full 32-bits
  638. jmp WOW16Done ;
  639. Entry WOW16GlobalUnlockFree
  640. push lParam.hi ;push segment of address to free
  641. call far ptr GLOBALHANDLE;
  642. or dx,ax ;valid handle?
  643. jz short gufree_done ;no
  644. push ax ;save a copy of hmem for the free
  645. push ax ;push hmem to unlock
  646. call far ptr GLOBALUNLOCK;
  647. pop cx ;recover copy of hmem
  648. or ax,ax ;is lock count now zero?
  649. jnz short gufree_err ;no
  650. push cx ;push hmem to free
  651. call far ptr GLOBALFREE ;
  652. gufree_exit: ;
  653. or ax,ax ;
  654. mov ax,1 ;if success, return TRUE; otherwise, FALSE
  655. jz short gufree_done ;
  656. gufree_err: ;
  657. sub ax,ax ;
  658. gufree_done: ;
  659. cwd ;
  660. jmp WOW16Done ;
  661. Entry WOW16FindResource
  662. push wParam ;push hTask
  663. call far ptr GetExpWinVer
  664. push ax ;save expwinver
  665. push wParam ;push hTask
  666. push lParam.hi ;push vpName
  667. push lParam.lo ;
  668. push hwnd ;push vpType
  669. push wMsg ;
  670. call far ptr FINDRESOURCE;
  671. ; or ax,ax ;
  672. ; jz short findres_done ;
  673. ;findres_done: ;
  674. cwd ;make return code a full 32-bits
  675. pop cx ; expwinver
  676. mov wGenUse1, cx
  677. jmp WOW16Done ;
  678. Entry WOW16LoadResource
  679. push wParam ;push hTask
  680. push lParam.lo ;push hResInfo
  681. call far ptr LOADRESOURCE;
  682. cwd ;make return code a full 32-bits
  683. jmp WOW16Done ;
  684. Entry WOW16FreeResource
  685. push wParam ;push hResData
  686. call far ptr FREERESOURCE;
  687. cmp ax,1
  688. sbb ax,ax
  689. cwd ;make return code a full 32-bits
  690. jmp WOW16Done
  691. Entry WOW16LockResource
  692. push wParam ;hResData
  693. call far ptr LOCKRESOURCE;
  694. push ax ; save res pointer
  695. push dx
  696. or dx,dx
  697. ; I commented out the following code because it is breaking the US builds
  698. ; in the case where hResData is bad. If you put code like this in, please
  699. ; comment in *detail* (with bug number perhaps) why you did.
  700. ; In this case, jz lres_err isn't accounting for the push ax, push dx
  701. ; instructions above. If there is a case where the stack is off by 4 bytes
  702. ; please put a note in as to how & why. - cmjones
  703. ;
  704. ;ifdef FE_SB ;avoid to break stack
  705. ; jz lres_err
  706. ;else
  707. jz lres_exit
  708. ;endif ; FE_SB
  709. push wParam ;push hResData
  710. call far ptr GLOBALSIZE
  711. lres_exit:
  712. mov wGenUse2,ax ;save size
  713. mov wGenUse1,dx ;
  714. pop dx
  715. pop ax
  716. jmp WOW16Done
  717. ; see "I commented out..." note above
  718. ;ifdef FE_SB ;avoid to break stack
  719. ;lres_err:
  720. ; xor ax,ax
  721. ; jmp WOW16Done
  722. ;endif ; FE_SB
  723. Entry WOW16SizeofResource
  724. push wParam ;push hTask
  725. push lParam.lo ;push hResInfo
  726. call far ptr SIZEOFRESOURCE ; DX:AX is DWORD size
  727. jmp WOW16Done
  728. Entry WOW16LockSegment
  729. push wParam ;push wSeg
  730. call far ptr LOCKSEGMENT
  731. sub dx,dx
  732. jmp WOW16Done
  733. Entry WOW16UnlockSegment
  734. push wParam ;push wSeg
  735. call far ptr UNLOCKSEGMENT
  736. cmp ax,1
  737. sbb ax,ax
  738. cwd ;make return code a full 32-bits
  739. jmp WOW16Done
  740. ;MikeTri Beginning of temporary hack for testing - 17-Aug-1992
  741. Entry WOW16GetDosPDB
  742. push ds ;Save DS
  743. SetKernelDS ;Pick up Kernel DS
  744. mov dx, Win_PDB ;Copy Windows PDB to DX (selector)
  745. mov ax,0 ;Move 0 to AX (offset)
  746. UnSetKernelDS ;Get rid of kernel DS
  747. pop ds ;Restore callers DS
  748. jmp WOW16Done ;Exit
  749. Entry WOW16GetDosSFT
  750. push ds ;Save DS
  751. SetKernelDS ;Pick up Kernel DS
  752. mov dx,pFileTable.sel ;Move SFT selector value to DX
  753. mov ax,pFileTable.off ;Move SFT offset value to AX
  754. UnSetKernelDS ;Get rid of kernel DS
  755. pop ds ;Restore callers DS
  756. jmp WOW16Done
  757. ;MikeTri End of temporary hack for testing - 17-Aug-1992
  758. Entry WOW16EnumMetaFileProc
  759. call [vpfnProc] ;call the apps MetaFile proc
  760. sub sp,size PARMEMP ;undo the effect of the proc's RET 0x10h
  761. jmp WOW16Done ;call back to WOW32
  762. Entry WOW16HookProc
  763. call [vpfnProc] ;call the apps Hook Proc.
  764. sub sp,size PARMHKP ;undo the effect of the proc's RET 0x08h
  765. jmp WOW16Done ;call back to WOW32
  766. Entry WOW16SetAbortProc
  767. call [vpfnProc] ;call the apps abort proc
  768. ; sub sp,size PARMSAP ;undo the effect of the proc's RET 0x04h
  769. ;
  770. ; Use 'bp' to restore 'sp' instead of subtracting 4bytes from sp. this is
  771. ; because Wordperfect's Informs doesn't pop the arguments off the stack.
  772. ; However it preserves 'bp'.
  773. ;
  774. ; Here in wow, sp is same as bp . The correct value is in 'bp' - see
  775. ; WOW16_From_CallBack16
  776. ;
  777. ; Similar fix can also be found in win31 - core\gdi, function queryabort()
  778. ;
  779. ; - nandurir
  780. ;
  781. mov sp, bp
  782. jmp WOW16Done ;call back to WOW32
  783. Entry WOW16SubClassProc
  784. push ds
  785. SetKernelDS ds
  786. mov ax, hUser
  787. pop ds ; restore ds
  788. UnSetKernelDS ds
  789. pop cx ; cx = the ordinal number
  790. push cx ; restore stack pointer
  791. push ax ; hModule
  792. push 0 ; hiword of ordinal number
  793. push cx ; the ordinal
  794. call GetProcAddress
  795. jmp WOW16Done ;call back to WOW32
  796. Entry WOW16SetCurDir
  797. call SetCurrentDrive ; on the stack is drive number;
  798. call WOW16SetCurrentDirectory ; on the stack is directory name;
  799. sub sp,size PARMDIR ; restore stack
  800. jmp WOW16Done ;call back to WOW32
  801. Entry WOW16SetDdeHandleFlag
  802. push wParam ;push hMem
  803. push wMsg ;push fSet
  804. call far ptr SETDDEHANDLEFLAG
  805. jmp WOW16Done ;
  806. Entry WOW16SetCursorIconFlag
  807. push wParam ;push hMem
  808. push wMsg ;push fSet
  809. call far ptr SETCURSORICONFLAG
  810. jmp WOW16Done ;
  811. Entry WOW16GetExePtr
  812. push wParam ;push hInstance
  813. call GetExePtr
  814. jmp WOW16Done
  815. ;ifdef FE_SB
  816. ;Entry WOW16SetFNotepad
  817. ; push ds
  818. ; SetKernelDS ; pick up Kernel DS
  819. ; mov ax,wParam
  820. ; mov hModNotepad,ax ; handle of notepad32
  821. ; pop ds ; restore ds
  822. ; UnSetKernelDS ds
  823. ; jmp WOW16Done
  824. ;endif ; FE_SB
  825. Entry WOW16ForceTaskExit
  826. mov ax,4CFFH ; Hung App Support Forces Current Task to Exit
  827. DOSCALL
  828. INT3_NEVER
  829. Entry WOW16GetModuleFilename
  830. push wParam ; hInstance
  831. push lParam.hi ; selector of filename buffer
  832. push lParam.lo ; offset of filename buffer
  833. push wMsg ; bytes in filename buffer
  834. call far ptr GetModuleFileName
  835. jmp WOW16Done ; Just return return value
  836. Entry WOW16WinExec
  837. push lParam.hi ; selector of lpszCmdLine
  838. push lParam.lo ; offset of lpszCmdLine
  839. push wParam ; fuCmdShow
  840. call far ptr WinExec
  841. jmp WOW16Done ; Just return return value
  842. Entry WOW16GetExpWinVer
  843. push wParam ;push hInstance
  844. call GetExpWinVer
  845. jmp WOW16Done
  846. Entry WOW16GetCurDir
  847. call WOW16GetCurrentDirectory
  848. sub sp,size PARMDIR ; restore stack
  849. jmp WOW16Done ;call back to WOW32
  850. Entry WOW16ForceTaskFault
  851. ; %OUT Ignore Impure warning A4100 its required for Forcing a GP Fault
  852. mov cs:gdtdsc,0 ; Force a GP Fault - Write to our CS
  853. jmp WOW16ForceTaskFault
  854. Entry WOW16ForceSegmentFault
  855. push es ; IsBadReadPtr can trash ES & BX
  856. push bx
  857. push lParam.hi ; selector of lp
  858. push lParam.lo ; offset of lp
  859. push 1 ; min byte size
  860. call far ptr IsBadReadPtr ; force segment fault or handle GPF
  861. pop bx
  862. pop es
  863. jmps WOW16Done
  864. Entry WOW16lstrcmp
  865. push ds ;Save DS
  866. SetKernelDS ;Pick up Kernel DS
  867. push word ptr lpstr1[2]
  868. push word ptr lpstr1[0]
  869. push word ptr lpstr2[2]
  870. push word ptr lpstr2[0]
  871. call [plstrcmp]
  872. UnSetKernelDS ;Get rid of kernel DS
  873. pop ds ;Restore callers DS
  874. jmps WOW16Done
  875. Entry WOW16ForegroundIdle
  876. mov ax,1689h ;notify application that the foreground
  877. int 2fh ;task has gone idle
  878. jmps WOW16Done
  879. Entry WOW16WinsockBlockHook
  880. call [vpfnProc] ;call the apps Hook Proc.
  881. jmps WOW16Done ;call back to WOW32
  882. Entry WOW16ChangeSelector
  883. push wParam ;push wSeg
  884. push wParam ;push wSeg
  885. call far ptr PRESTOCHANGOSELECTOR;
  886. cCall SetOwner,<wParam,-1> ; Make this new guy the owner
  887. jmps WOW16Done ; Just return return value
  888. Entry WOW16GetDibSize
  889. push wParam ; selector for which size is being queryed
  890. call far ptr GetSelectorLimit
  891. jmps WOW16Done ; Just return return value
  892. Entry WOW16GetDibFlags
  893. cCall get_sel_flags,<wParam>
  894. jmps WOW16Done ; Just return return value
  895. Entry WOW16SetDibSel
  896. cCall set_sel_for_dib,<wParam,wMsg,lParam.lo,lParam.hi,hwnd>
  897. jmps WOW16Done ; Just return return value
  898. Entry WOW16FreeDibSel
  899. cCall RestoreDib,<wParam,wMsg,lParam.hi,lParam.lo>
  900. jmps WOW16Done ; Just return return value
  901. Entry WOW16Debug
  902. int 3 ;that's all folks
  903. ;fall into WOW16Done
  904. Entry WOW16Done
  905. mov cbackAX, ax ; set return value
  906. mov cbackDX, dx
  907. mov bp, word ptr vfSP ; verify the saved ES is still valid
  908. .386p
  909. verr [bp].vf_wES ; see bug #121760
  910. jz @f ; jump if still valid
  911. mov [bp].vf_wES, es ; if not, update saved ES with a known good one
  912. @@: ; - cmjones 11/12/97
  913. mov bp, [bp].vf_wLocalBP
  914. ; fall thru. the return values are set for a 'real' callback only
  915. ; don't use 'entry' macro for wow16doneboot as it 'align 16s' the label
  916. ; thus putting extra instructions between cbackDx, dx and mov bp,si.
  917. public WOW16DoneBoot ; tasking.asm needs this label
  918. WOW16DoneBoot: ; tasking.asm needs this label
  919. push bp ;rebuild the frame
  920. push RET_RETURN ;push default wRetID (do not move see tasking.asm)
  921. SetKernelDS ds
  922. push [curTDB] ;save current 16bit task handle (see tasking.asm)
  923. mov [wCurTaskSS],ss ;save current task SS
  924. mov [wCurTaskBP],bp ;save current task BP
  925. mov TraceOff,1h ; Don't allow debuggers to trace to 32 bit land
  926. test [FastWOWCbRetCS], 0ffffh
  927. jz WOW16SlowCBReturn
  928. .386
  929. call fword ptr [FastWOWCbRet]
  930. .286
  931. ; don't put any code here!!!
  932. ; when fastbopping, after kernel has booted we return
  933. ; directly to WOW16CallContinue
  934. jmp WOW16CallContinue
  935. WOW16SlowCBReturn:
  936. FBOP BOP_UNSIMULATE,,FastBop
  937. jmp WOW16CallContinue
  938. cEnd nogen ; WOW16Call
  939. ;
  940. ; Initialize address of fast Bop entry to monitor.
  941. ;
  942. cProc WOWFastBopInit,<PUBLIC,FAR>
  943. cBegin
  944. push ds
  945. push es
  946. push bx
  947. push dx
  948. DPMIBOP GetFastBopAddress
  949. CheckKernelDS ds ; On debug, check that DS is really kernels
  950. ReSetKernelDS ds ; Assume it otherwise.
  951. ;
  952. ; Set up FastBop address (for DPMI, and WOW without WOW16FastVector)
  953. mov word ptr [FastBop],bx
  954. mov word ptr [FastBop + 2],dx
  955. mov word ptr [FastBop + 4],es
  956. or bx,dx
  957. jz NoFastWow
  958. call far ptr WOWGetFastAddress
  959. mov word ptr [FastWOW],ax
  960. mov word ptr [FastWOW+2],dx
  961. or ax,dx
  962. jz NoFastWow
  963. mov word ptr [FastWOWCS],es
  964. mov word ptr [WOWFastBopping],1
  965. call far ptr WOWGetFastCbRetAddress
  966. mov word ptr [FastWOWCbRet],ax
  967. mov word ptr [FastWOWCbRet+2],dx
  968. or ax,dx
  969. jz NoFastCb
  970. mov word ptr [FastWOWCbRetCS],es
  971. NoFastCb:
  972. NoFastWow:
  973. call far ptr WowGetFlatAddressArray
  974. mov word ptr [FlatAddressArray],ax
  975. mov word ptr [FlatAddressArray + 2],dx
  976. pop dx
  977. pop bx
  978. pop es
  979. pop ds
  980. UnSetKernelDS ds
  981. cEnd WOWFastBopInit
  982. cProc WOWNotifyTHHOOK,<PUBLIC,FAR>
  983. cBegin
  984. CheckKernelDS ds
  985. ReSetKernelDS ds
  986. mov DebugWOW,0
  987. push 1
  988. push seg THHOOK
  989. push offset THHOOK
  990. push DBG_TOOLHELP
  991. FBOP BOP_DEBUGGER,,FastBop
  992. add sp,+8
  993. push seg cur_drive_owner
  994. push offset cur_drive_owner
  995. push topPDB
  996. push 0
  997. push seg LockTDB
  998. push offset LockTDB
  999. push seg DebugWOW
  1000. push offset DebugWOW
  1001. push seg curTDB
  1002. push offset curTDB
  1003. push seg num_tasks
  1004. push offset num_tasks
  1005. push codeBase
  1006. push codeOffset Int21Handler
  1007. call WOWNotifyWOW32
  1008. UnSetKernelDS ds
  1009. cEnd WOWNotifyTHHOOK
  1010. cProc WOWQueryDebug,<PUBLIC,FAR>
  1011. cBegin
  1012. push ds
  1013. SetKernelDS
  1014. mov ax,DebugWOW
  1015. pop ds
  1016. UnSetKernelDS
  1017. cEnd WOWQueryDebug
  1018. ;*--------------------------------------------------------------------------*
  1019. ;*
  1020. ;* WOW16GetCurrentDirectory() -
  1021. ;*
  1022. ;* - Drive =0 implies 'current' drive.
  1023. ;*--------------------------------------------------------------------------*
  1024. cProc WOW16GetCurrentDirectory, <NEAR, PUBLIC>, <SI, DI>
  1025. ParmD lpDest
  1026. ParmW Drive
  1027. cBegin
  1028. push ds ; Preserve DS
  1029. les di,lpDest ; ES:DI = lpDest
  1030. push es
  1031. pop ds ; DS:DI = lpDest
  1032. cld
  1033. mov ax,Drive ; AX = Drive
  1034. or al,al ; Zero?
  1035. jnz CDGotDrive ; Yup, skip
  1036. mov ah,19h ; Get Current Disk
  1037. DOSCALL
  1038. inc al ; Convert to logical drive number
  1039. CDGotDrive:
  1040. mov dl,al ; DL = Logical Drive Number
  1041. add al, 040h ; drive letter
  1042. mov ah, 03Ah ; ':'
  1043. stosw
  1044. mov al,'\' ; Start string with a backslash
  1045. stosb
  1046. mov byte ptr es:[di],0 ; Null terminate in case of error
  1047. mov si,di ; DS:SI = lpDest[1]
  1048. mov ah,47h ; Get Current Directory
  1049. DOSCALL
  1050. jc CDExit ; Skip if error
  1051. xor ax,ax ; Return FALSE if no error
  1052. CDExit:
  1053. pop ds ; Restore DS
  1054. cEnd
  1055. ;*--------------------------------------------------------------------------*
  1056. ;* *
  1057. ;* WOW16SetCurrentDirectory() - *
  1058. ;* *
  1059. ;*--------------------------------------------------------------------------*
  1060. cProc WOW16SetCurrentDirectory, <NEAR, PUBLIC>,<si,di>
  1061. ParmD lpDirName
  1062. cBegin
  1063. push ds ; Preserve DS
  1064. lds dx,lpDirName ; DS:DX = lpDirName
  1065. mov ah,3Bh ; Change Current Directory
  1066. DOSCALL
  1067. jc SCDExit ; Skip on error
  1068. xor ax,ax ; Return FALSE if successful
  1069. SCDExit:
  1070. pop ds ; Restore DS
  1071. cEnd
  1072. ;*--------------------------------------------------------------------------*
  1073. ;* *
  1074. ;* SetCurrentDrive() - *
  1075. ;* *
  1076. ;*--------------------------------------------------------------------------*
  1077. ; Returns the number of drives in AX.
  1078. cProc SetCurrentDrive, <NEAR, PUBLIC>,<si,di>
  1079. ParmW Drive
  1080. cBegin
  1081. mov dx,Drive
  1082. mov ah,0Eh ; Set Current Drive
  1083. DOSCALL
  1084. sub ah,ah ; Zero out AH
  1085. cEnd
  1086. ; --- GetTaskHandle0 ---
  1087. ; ripped out piece of GetTaskHandle, taken from CONTEXT.ASM which was not
  1088. ; part of WOW's kernel, so we copied this little piece out.
  1089. ;
  1090. GetTaskHandle0:
  1091. or ax,ax
  1092. jnz gt1
  1093. SetKernelDS es
  1094. mov ax,curTDB
  1095. gt1: mov es,ax
  1096. assumes es, nothing
  1097. ; cmp es:[TDB_sig],TDB_SIGNATURE
  1098. ; jne gt2
  1099. ret
  1100. ;gt2: kerror ERR_TASKID,<GetTaskHandle: Invalid task handle>
  1101. ; ret
  1102. ;*--------------------------------------------------------------------------*
  1103. ;* *
  1104. ;* WowSetExitOnLastApp(WORD fExitOnLastApp) *
  1105. ;* Sets fExitOnLastApp variable which causes kernel to exit when the *
  1106. ;* last app except WowExec exits. Called by WowExec for seperate *
  1107. ;* WOW VDMs, which need to exit after the last app closes. *
  1108. ;* *
  1109. ;*--------------------------------------------------------------------------*
  1110. cProc WowSetExitOnLastApp, <PUBLIC, FAR>
  1111. ParmW fExit
  1112. cBegin
  1113. SetKernelDS
  1114. mov ax, fExit
  1115. mov fExitOnLastApp, al
  1116. cEnd
  1117. ;-----------------------------------------------------------------------;
  1118. ; WowFixWin32CurDir
  1119. ;
  1120. ; Called by thunks for PrivateProfile APIs which need Win32 current
  1121. ; directory to reflect Win16 current directory (imagine that!)
  1122. ;
  1123. ; Trashes AX, DX which shouldn't matter
  1124. ;
  1125. ; History:
  1126. ; Mon Dec 20, 1993 -by- Dave Hart [DaveHart]
  1127. ; Don't ask me about current directories and WOW! I'll deny it all!
  1128. ;-----------------------------------------------------------------------;
  1129. Entry WowFixWin32CurDir
  1130. push ds
  1131. SetKernelDS
  1132. mov ax,[CurTDB]
  1133. or ax,ax
  1134. jz WFW32CD_Exit
  1135. mov ds,ax ; DS points to TDB
  1136. UnSetKernelDS
  1137. cmp ds:[TDB_sig],TDB_SIGNATURE
  1138. jne WFW32CD_Exit
  1139. mov dl,ds:[TDB_Drive]
  1140. and dl,7fh
  1141. mov ah,0Eh ; change drive
  1142. DOSCALL
  1143. mov dx,TDB_LFNDirectory ; DS:DX points to TDB curdir
  1144. mov ah,3Bh ; change directory
  1145. DOSCALL
  1146. if KDEBUG
  1147. jnc WFW32CD_Exit
  1148. krDebugOut DEB_WARN, "WowFixWin32CurDir: DOS fn 3B fails error #AX"
  1149. endif
  1150. WFW32CD_Exit:
  1151. pop ds
  1152. ret
  1153. ; sudeepb 11-May-1994
  1154. ;
  1155. ; This hackcheck is for simcity. Simcity does a GlobalSize on GDI.EXE and
  1156. ; USER.EXE to figure out how much free resources are available. WOW's USER
  1157. ; GDI have pretty small DGROUP, hence the size returns fails the check of
  1158. ; this app. So we need to fake a bigger size.
  1159. ;
  1160. cProc HackCheck,<PUBLIC,NEAR>
  1161. parmW handle
  1162. cBegin]
  1163. push es
  1164. SetKernelDS es
  1165. ; first check in the TDB that the currently running app is SCW.
  1166. mov ax,curtdb
  1167. mov es,ax
  1168. xor ax,ax
  1169. cmp word ptr es:[0f2h],4353h ; SC (mod name in TDB at f2 offset)
  1170. jne hc5
  1171. cmp word ptr es:[0f4h],0057h ; W
  1172. jne hc5
  1173. ; Its SCW. Now get the module table for the given handle and check if its
  1174. ; for USER.EXE and GDI.EXE
  1175. cCall GetExePtr,<handle>
  1176. or ax,ax
  1177. jz hc5
  1178. mov ds,ax
  1179. mov si,ds:[ne_pfileinfo]
  1180. lea dx,[si].opFile ; DS:DX -> path
  1181. cCall WowCheckUserGdi,<ds,dx> ; Much easier to check this in 32bit land.
  1182. hc5:
  1183. pop es
  1184. cEnd
  1185. ;-----------------------------------------------------------------------;
  1186. ; WowSetCompatHandle
  1187. ;
  1188. ; This routine takes a single parameter and saves it in the TDB. It is
  1189. ; used to take care of a bug in dBase where it confuses handle values.
  1190. ; This is a private API called by USER.EXE.
  1191. ;
  1192. ; All registers must be saved. DS is saved automatically by cmacros.
  1193. ; History:
  1194. ;-----------------------------------------------------------------------;
  1195. cProc WowSetCompatHandle, <PUBLIC, FAR>
  1196. ParmW handle
  1197. cBegin
  1198. push bx
  1199. SetKernelDS
  1200. mov bx,[CurTDB]
  1201. or bx,bx
  1202. jz @f ;check for zero just in case
  1203. mov ds,bx ; DS points to TDB
  1204. UnSetKernelDS
  1205. mov bx, handle
  1206. mov ds:[TDB_CompatHandle],bx ;save it here
  1207. @@:
  1208. pop bx
  1209. cEnd
  1210. sEND CODE
  1211. end