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.

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