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.

927 lines
22 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WCALL16.C
  8. * WOW32 16-bit message/callback support
  9. *
  10. * History:
  11. * Created 11-Mar-1991 by Jeff Parsons (jeffpar)
  12. * Changed 18-Aug-1992 by Mike Tricker (MikeTri) Added DOS PDB and SFT functions
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. MODNAME(wcall16.c);
  17. #define WOWFASTEDIT
  18. #ifdef WOWFASTEDIT
  19. typedef struct _LOCALHANDLEENTRY {
  20. WORD lhe_address; // actual address of object
  21. BYTE lhe_flags; // flags and priority level
  22. BYTE lhe_count; // lock count
  23. } LOCALHANDLEENTRY, *PLOCALHANDLEENTRY;
  24. #define LA_MOVEABLE 0x0002 // moveable or fixed?
  25. #define LHE_DISCARDED 0x0040 // Marks objects that have been discarded.
  26. #endif
  27. /* Common callback functions
  28. */
  29. HANDLE LocalAlloc16(WORD wFlags, INT cb, HANDLE hInstance)
  30. {
  31. PARM16 Parm16;
  32. VPVOID vp = 0;
  33. if (LOWORD(hInstance) == 0 ) { /* if lo word == 0, then this is a 32-bit
  34. hInstance, which makes no sense */
  35. WOW32ASSERT(LOWORD(hInstance));
  36. return (HANDLE)0;
  37. }
  38. if (cb < 0 || cb > 0xFFFF) {
  39. WOW32ASSERT(cb > 0 && cb <= 0xFFFF);
  40. return (HANDLE)0;
  41. }
  42. Parm16.WndProc.wMsg = LOWORD(hInstance) | 1;
  43. Parm16.WndProc.wParam = wFlags;
  44. Parm16.WndProc.lParam = cb;
  45. CallBack16(RET_LOCALALLOC, &Parm16, 0, &vp);
  46. if (LOWORD(vp) == 0)
  47. vp = 0;
  48. return (HANDLE)vp;
  49. }
  50. HANDLE LocalReAlloc16(HANDLE hMem, INT cb, WORD wFlags)
  51. {
  52. PARM16 Parm16;
  53. VPVOID vp = 0;
  54. if (HIWORD(hMem) == 0 || cb < 0 || cb > 0xFFFF) {
  55. WOW32ASSERT(HIWORD(hMem) && cb >= 0 && cb <= 0xFFFF);
  56. return (HANDLE)0;
  57. }
  58. LOGDEBUG(4,("LocalRealloc DS = %x, hMem = %x, bytes = %x, flags = %x\n",HIWORD(hMem),LOWORD(hMem),cb,wFlags));
  59. Parm16.WndProc.lParam = (LONG)hMem;
  60. Parm16.WndProc.wParam = wFlags;
  61. Parm16.WndProc.wMsg = (WORD)cb;
  62. CallBack16(RET_LOCALREALLOC, &Parm16, 0, &vp);
  63. if (LOWORD(vp) == 0)
  64. vp = 0;
  65. return (HANDLE)vp;
  66. }
  67. #ifndef WOWFASTEDIT
  68. VPVOID LocalLock16(HANDLE hMem)
  69. {
  70. PARM16 Parm16;
  71. VPVOID vp = 0;
  72. if (HIWORD(hMem) == 0) {
  73. WOW32ASSERT(HIWORD(hMem) != 0);
  74. return (VPVOID)0;
  75. }
  76. Parm16.WndProc.lParam = (LONG)hMem;
  77. CallBack16(RET_LOCALLOCK, &Parm16, 0, &vp);
  78. return vp;
  79. }
  80. BOOL LocalUnlock16(HANDLE hMem)
  81. {
  82. PARM16 Parm16;
  83. VPVOID vp = FALSE;
  84. if (HIWORD(hMem) == 0) {
  85. WOW32ASSERT(HIWORD(hMem));
  86. return FALSE;
  87. }
  88. Parm16.WndProc.lParam = (LONG)hMem;
  89. CallBack16(RET_LOCALUNLOCK, &Parm16, 0, &vp);
  90. return (BOOL)vp;
  91. }
  92. #else
  93. VPVOID LocalLock16(HANDLE hMem)
  94. {
  95. WORD h16;
  96. LONG retval;
  97. if (HIWORD(hMem) == 0) {
  98. WOW32ASSERT(HIWORD(hMem) != 0);
  99. return (VPVOID)0;
  100. }
  101. h16 = LOWORD(hMem);
  102. retval = (VPVOID)hMem;
  103. if (h16 & LA_MOVEABLE) {
  104. PLOCALHANDLEENTRY plhe;
  105. GETVDMPTR(hMem, sizeof(*plhe), plhe);
  106. if (plhe->lhe_flags & LHE_DISCARDED) {
  107. goto LOCK1;
  108. }
  109. plhe->lhe_count++;
  110. if (!plhe->lhe_count)
  111. plhe->lhe_count--;
  112. LOCK1:
  113. LOW(retval) = plhe->lhe_address;
  114. FLUSHVDMPTR((ULONG)hMem, sizeof(*plhe), plhe);
  115. FREEVDMPTR(plhe);
  116. }
  117. if (LOWORD(retval) == 0)
  118. retval = 0;
  119. return retval;
  120. }
  121. BOOL LocalUnlock16(HANDLE hMem)
  122. {
  123. WORD h16;
  124. BOOL rc;
  125. PLOCALHANDLEENTRY plhe;
  126. BYTE count;
  127. if (HIWORD(hMem) == 0) {
  128. WOW32ASSERT(HIWORD(hMem));
  129. return FALSE;
  130. }
  131. rc = FALSE;
  132. h16 = LOWORD(hMem);
  133. if (!(h16 & LA_MOVEABLE)) {
  134. goto UNLOCK2;
  135. }
  136. GETVDMPTR(hMem, sizeof(*plhe), plhe);
  137. if (plhe->lhe_flags & LHE_DISCARDED)
  138. goto UNLOCK1;
  139. count = plhe->lhe_count;
  140. count--;
  141. if (count >= (BYTE)(0xff-1))
  142. goto UNLOCK1;
  143. plhe->lhe_count = count;
  144. rc = (BOOL)((SHORT)count);
  145. FLUSHVDMPTR((ULONG)hMem, sizeof(*plhe), plhe);
  146. UNLOCK1:
  147. FREEVDMPTR(plhe);
  148. UNLOCK2:
  149. return rc;
  150. }
  151. #endif // WOWFASTEDIT
  152. WORD LocalSize16(HANDLE hMem)
  153. {
  154. PARM16 Parm16;
  155. VPVOID vp = 0;
  156. if (HIWORD(hMem) == 0) {
  157. WOW32ASSERT(HIWORD(hMem));
  158. return FALSE;
  159. }
  160. Parm16.WndProc.lParam = (LONG)hMem;
  161. CallBack16(RET_LOCALSIZE, &Parm16, 0, &vp);
  162. return (WORD)vp;
  163. }
  164. HANDLE LocalFree16(HANDLE hMem)
  165. {
  166. PARM16 Parm16;
  167. VPVOID vp = FALSE;
  168. if (HIWORD(hMem) == 0) {
  169. WOW32ASSERT(HIWORD(hMem));
  170. return (HANDLE)0;
  171. }
  172. Parm16.WndProc.lParam = (LONG)hMem;
  173. CallBack16(RET_LOCALFREE, &Parm16, 0, &vp);
  174. if (LOWORD(vp) == 0) {
  175. vp = 0;
  176. } else {
  177. WOW32ASSERT(LOWORD(vp) == LOWORD(hMem));
  178. vp = (VPVOID)hMem;
  179. }
  180. return (HANDLE)vp;
  181. }
  182. BOOL LockSegment16(WORD wSeg)
  183. {
  184. PARM16 Parm16;
  185. VPVOID vp = FALSE;
  186. Parm16.WndProc.wParam = wSeg;
  187. CallBack16(RET_LOCKSEGMENT, &Parm16, 0, &vp);
  188. return (BOOL)vp;
  189. }
  190. BOOL UnlockSegment16(WORD wSeg)
  191. {
  192. PARM16 Parm16;
  193. VPVOID vp = FALSE;
  194. Parm16.WndProc.wParam = wSeg;
  195. CallBack16(RET_UNLOCKSEGMENT, &Parm16, 0, &vp);
  196. return (BOOL)vp;
  197. }
  198. VPVOID WOWGlobalAllocLock16(WORD wFlags, DWORD cb, HMEM16 *phMem)
  199. {
  200. PARM16 Parm16;
  201. VPVOID vp = 0;
  202. Parm16.WndProc.wParam = wFlags;
  203. Parm16.WndProc.lParam = cb;
  204. CallBack16(RET_GLOBALALLOCLOCK, &Parm16, 0, &vp);
  205. if (vp) {
  206. // Get handle of 16-bit object
  207. if (phMem) {
  208. *phMem = Parm16.WndProc.wParam;
  209. }
  210. }
  211. return vp;
  212. }
  213. HMEM16 WOWGlobalAlloc16(WORD wFlags, DWORD cb)
  214. {
  215. HMEM16 hMem;
  216. VPVOID vp;
  217. if (vp = WOWGlobalAllocLock16(wFlags, cb, &hMem)) {
  218. WOWGlobalUnlock16(hMem);
  219. } else {
  220. hMem = 0;
  221. }
  222. return hMem;
  223. }
  224. VPVOID WOWGlobalLockSize16(HMEM16 hMem, PDWORD pcb)
  225. {
  226. PARM16 Parm16;
  227. VPVOID vp = 0;
  228. Parm16.WndProc.wParam = hMem;
  229. CallBack16(RET_GLOBALLOCK, &Parm16, 0, &vp);
  230. // Get size of 16-bit object (will be 0 if lock failed)
  231. if (pcb) {
  232. *pcb = Parm16.WndProc.lParam;
  233. }
  234. return vp;
  235. }
  236. VPVOID WOWGlobalLock16(HMEM16 hMem)
  237. {
  238. return WOWGlobalLockSize16(hMem, NULL);
  239. }
  240. BOOL WOWGlobalUnlock16(HMEM16 hMem)
  241. {
  242. PARM16 Parm16;
  243. VPVOID vp = FALSE;
  244. Parm16.WndProc.wParam = hMem;
  245. CallBack16(RET_GLOBALUNLOCK, &Parm16, 0, &vp);
  246. return (BOOL)vp;
  247. }
  248. HMEM16 WOWGlobalUnlockFree16(VPVOID vpMem)
  249. {
  250. PARM16 Parm16;
  251. VPVOID vp = FALSE;
  252. Parm16.WndProc.lParam = vpMem;
  253. CallBack16(RET_GLOBALUNLOCKFREE, &Parm16, 0, &vp);
  254. return (HMEM16)vp;
  255. }
  256. HMEM16 WOWGlobalFree16(HMEM16 hMem)
  257. {
  258. VPVOID vp;
  259. if (vp = WOWGlobalLock16(hMem)) {
  260. hMem = WOWGlobalUnlockFree16(vp);
  261. } else {
  262. // On failure we return the passed-in handle,
  263. // so there's nothing to do.
  264. }
  265. return hMem;
  266. }
  267. HAND16 GetExePtr16( HAND16 hInst )
  268. {
  269. PARM16 Parm16;
  270. ULONG ul;
  271. PTD ptd;
  272. INT i;
  273. if (hInst == 0) return (HAND16)0;
  274. //
  275. // see if this is the hInst for the current task
  276. //
  277. ptd = CURRENTPTD();
  278. if (hInst == ptd->hInst16) {
  279. return ptd->hMod16;
  280. }
  281. //
  282. // check the cache
  283. //
  284. for (i = 0; i < CHMODCACHE; i++) {
  285. if (ghModCache[i].hInst16 == hInst)
  286. return ghModCache[i].hMod16;
  287. }
  288. /*
  289. ** Function returns a hModule, given an hInstance
  290. */
  291. Parm16.WndProc.wParam = hInst;
  292. CallBack16(RET_GETEXEPTR, &Parm16, 0, &ul);
  293. //
  294. // GetExePtr(hmod) returns hmod, don't cache these.
  295. //
  296. if (hInst != (HAND16)LOWORD(ul)) {
  297. //
  298. // update the cache
  299. // slide everybody down 1 entry, put this new guy at the top
  300. //
  301. RtlMoveMemory(ghModCache+1, ghModCache, sizeof(HMODCACHE)*(CHMODCACHE-1));
  302. ghModCache[0].hInst16 = hInst;
  303. ghModCache[0].hMod16 = (HAND16)LOWORD(ul);
  304. }
  305. return (HAND16)LOWORD(ul);
  306. }
  307. WORD GetModuleFileName16( HAND16 hInst, VPVOID lpszModuleName, WORD cchModuleName )
  308. {
  309. PARM16 Parm16;
  310. ULONG ul;
  311. if (hInst == 0) return 0;
  312. Parm16.WndProc.wParam = hInst;
  313. Parm16.WndProc.lParam = lpszModuleName;
  314. Parm16.WndProc.wMsg = cchModuleName;
  315. CallBack16(RET_GETMODULEFILENAME, &Parm16, 0, &ul );
  316. return( LOWORD(ul) );
  317. }
  318. ULONG GetDosPDB16(VOID)
  319. {
  320. PARM16 Parm16;
  321. DWORD dwReturn = 0;
  322. CallBack16(RET_GETDOSPDB, &Parm16, 0, &dwReturn);
  323. return (ULONG)dwReturn;
  324. }
  325. ULONG GetDosSFT16(VOID)
  326. {
  327. PARM16 Parm16;
  328. DWORD dwReturn = 0;
  329. CallBack16(RET_GETDOSSFT, &Parm16, 0, &dwReturn);
  330. return (ULONG)dwReturn;
  331. }
  332. // Given a data selector change it into a code selector
  333. WORD ChangeSelector16(WORD wSeg)
  334. {
  335. PARM16 Parm16;
  336. VPVOID vp = FALSE;
  337. Parm16.WndProc.wParam = wSeg;
  338. CallBack16(RET_CHANGESELECTOR, &Parm16, 0, &vp);
  339. return LOWORD(vp);
  340. }
  341. VPVOID RealLockResource16(HMEM16 hMem, PINT pcb)
  342. {
  343. PARM16 Parm16;
  344. VPVOID vp = 0;
  345. Parm16.WndProc.wParam = hMem;
  346. CallBack16(RET_LOCKRESOURCE, &Parm16, 0, &vp);
  347. // Get size of 16-bit object (will be 0 if lock failed)
  348. if (pcb) {
  349. *pcb = Parm16.WndProc.lParam;
  350. }
  351. return vp;
  352. }
  353. int WINAPI WOWlstrcmp16(LPCWSTR lpString1, LPCWSTR lpString2)
  354. {
  355. PARM16 Parm16;
  356. DWORD dwReturn = 0;
  357. DWORD cb1, cb2;
  358. VPSTR vp1, vp2;
  359. LPSTR p1, p2;
  360. //
  361. // to handle DBCS correctly allocate enough room
  362. // for two DBCS bytes for every unicode char.
  363. //
  364. cb1 = sizeof(WCHAR) * (wcslen(lpString1) + 1);
  365. cb2 = sizeof(WCHAR) * (wcslen(lpString2) + 1);
  366. // be sure allocation size matches stackfree16() size below
  367. vp1 = stackalloc16(cb1 + cb2);
  368. vp2 = vp1 + cb1;
  369. p1 = VDMPTR(vp1, cb1);
  370. p2 = p1 + cb1;
  371. RtlUnicodeToMultiByteN(
  372. p1,
  373. cb1,
  374. NULL,
  375. (LPWSTR) lpString1, // cast because arg isn't declared const
  376. cb1
  377. );
  378. RtlUnicodeToMultiByteN(
  379. p2,
  380. cb2,
  381. NULL,
  382. (LPWSTR) lpString2, // cast because arg isn't declared const
  383. cb2
  384. );
  385. FREEVDMPTR(p1);
  386. Parm16.lstrcmpParms.lpstr1 = vp1;
  387. Parm16.lstrcmpParms.lpstr2 = vp2;
  388. CallBack16(RET_LSTRCMP, &Parm16, 0, &dwReturn);
  389. stackfree16(vp1, (cb1 + cb2));
  390. return (int)(short int)LOWORD(dwReturn);
  391. }
  392. DWORD WOWCallback16(DWORD vpFn, DWORD dwParam)
  393. {
  394. PARM16 Parm16;
  395. VPVOID vp;
  396. //
  397. // Copy DWORD parameter to PARM16 structure.
  398. //
  399. RtlCopyMemory(&Parm16.WOWCallback16.wArgs, &dwParam, sizeof(dwParam));
  400. //
  401. // Use semi-slimy method to pass argument size to CallBack16.
  402. //
  403. vp = (VPVOID) sizeof(dwParam);
  404. CallBack16(RET_WOWCALLBACK16, &Parm16, (VPPROC)vpFn, &vp);
  405. return (DWORD)vp;
  406. }
  407. BOOL WOWCallback16Ex(
  408. DWORD vpFn,
  409. DWORD dwFlags,
  410. DWORD cbArgs,
  411. PVOID pArgs,
  412. PDWORD pdwRetCode
  413. )
  414. {
  415. #ifdef DEBUG
  416. static BOOL fFirstTime = TRUE;
  417. if (fFirstTime) {
  418. //
  419. // Ensure that wownt32.h's definition of WCB16_MAX_CBARGS
  420. // matches wow.h's definition of PARMWCB16.
  421. //
  422. WOW32ASSERT( WCB16_MAX_CBARGS == sizeof(PARMWCB16) );
  423. //
  424. // If the PARMWCB16 structure is smaller than the PARM16
  425. // union, we should increase the size of PARMWCB16 and
  426. // WCB16_MAX_CBARG to allow the use of the extra bytes.
  427. //
  428. WOW32ASSERT( sizeof(PARMWCB16) == sizeof(PARM16) );
  429. fFirstTime = FALSE;
  430. }
  431. #endif // DEBUG
  432. if (cbArgs > sizeof(PARM16)) {
  433. LOGDEBUG(LOG_ALWAYS, ("WOWCallback16V: cbArgs = %u, must be <= %u",
  434. cbArgs, (unsigned) sizeof(PARM16)));
  435. SetLastError(ERROR_INVALID_PARAMETER);
  436. return FALSE;
  437. }
  438. //
  439. // For cdecl functions we don't want to "sub SP, cbArgs" after calling
  440. // the function, so we pass 0 as cbArgs to the 16-bit side.
  441. //
  442. if (dwFlags & WCB16_CDECL) {
  443. cbArgs = 0;
  444. }
  445. //
  446. // Use semi-slimy method to pass argument size to CallBack16.
  447. //
  448. *pdwRetCode = cbArgs;
  449. CallBack16(RET_WOWCALLBACK16, (PPARM16)pArgs, (VPPROC)vpFn, (PVPVOID)pdwRetCode);
  450. return TRUE;
  451. }
  452. BOOL CallBack16(INT iRetID, PPARM16 pParm16, VPPROC vpfnProc, PVPVOID pvpReturn)
  453. {
  454. #ifdef DEBUG
  455. static PSZ apszCallBacks[] = {
  456. "ERROR:RETURN", // RET_RETURN (not a callback!)
  457. "ERROR:DEBUGRETURN", // RET_DEBUGRETURN (not a callback!)
  458. "DEBUG", // RET_DEBUG
  459. "WNDPROC", // RET_WNDPROC
  460. "ENUMFONTPROC", // RET_ENUMFONTPROC
  461. "ENUMWINDOWPROC", // RET_ENUMWINDOWPROC
  462. "LOCALALLOC", // RET_LOCALALLOC
  463. "LOCALREALLOC", // RET_LOCALREALLOC
  464. "LOCALLOCK", // RET_LOCALLOCK
  465. "LOCALUNLOCK", // RET_LOCALUNLOCK
  466. "LOCALSIZE", // RET_LOCALSIZE
  467. "LOCALFREE", // RET_LOCALFREE
  468. "GLOBALALLOCLOCK", // RET_GLOBALALLOCLOCK
  469. "GLOBALLOCK", // RET_GLOBALLOCK
  470. "GLOBALUNLOCK", // RET_GLOBALUNLOCK
  471. "GLOBALUNLOCKFREE", // RET_GLOBALUNLOCKFREE
  472. "FINDRESOURCE", // RET_FINDRESOURCE
  473. "LOADRESOURCE", // RET_LOADRESOURCE
  474. "FREERESOURCE", // RET_FREERESOURCE
  475. "LOCKRESOURCE", // RET_LOCKRESOURCE
  476. "UNLOCKRESOURCE", // RET_UNLOCKRESOURCE
  477. "SIZEOFRESOURCE", // RET_SIZEOFRESOURCE
  478. "LOCKSEGMENT", // RET_LOCKSEGMENT
  479. "UNLOCKSEGMENT", // RET_UNLOCKSEGMENT
  480. "ENUMMETAFILEPROC", // RET_ENUMMETAFILEPROC
  481. "TASKSTARTED ", // RET_TASKSTARTED
  482. "HOOKPROC", // RET_HOOKPROC
  483. "SUBCLASSPROC", // RET_SUBCLASSPROC
  484. "LINEDDAPROC", // RET_LINEDDAPROC
  485. "GRAYSTRINGPROC", // RET_GRAYSTRINGPROC
  486. "FORCETASKEXIT", // RET_FORCETASKEXIT
  487. "SETCURDIR", // RET_SETCURDIR
  488. "ENUMOBJPROC", // RET_ENUMOBJPROC
  489. "SETCURSORICONFLAG", // RET_SETCURSORICONFLAG
  490. "SETABORTPROC", // RET_SETABORTPROC
  491. "ENUMPROPSPROC", // RET_ENUMPROPSPROC
  492. "FORCESEGMENTFAULT", // RET_FORCESEGMENTFAULT
  493. "LSTRCMP", // RET_LSTRCMP
  494. "UNUSEDFUNC", //
  495. "UNUSEDFUNC", //
  496. "UNUSEDFUNC", //
  497. "UNUSEDFUNC", //
  498. "GETEXEPTR", // RET_GETEXEPTR
  499. "UNUSEDFUNC", //
  500. "FORCETASKFAULT", // RET_FORCETASKFAULT
  501. "GETEXPWINVER", // RET_GETEXPWINVER
  502. "GETCURDIR", // RET_GETCURDIR
  503. "GETDOSPDB", // RET_GETDOSPDB
  504. "GETDOSSFT", // RET_GETDOSSFT
  505. "FOREGROUNDIDLE", // RET_FOREGROUNDIDLE
  506. "WINSOCKBLOCKHOOK", // RET_WINSOCKBLOCKHOOK
  507. "WOWDDEFREEHANDLE", // RET_WOWDDEFREEHANDLE
  508. "CHANGESELECTOR", // RET_CHANGESELECTOR
  509. "GETMODULEFILENAME", // RET_GETMODULEFILENAME
  510. "WORDBREAKPROC", // RET_WORDBREAKPROC
  511. "WINEXEC", // RET_WINEXEC
  512. "WOWCALLBACK16", // RET_WOWCALLBACK16
  513. "GETDIBSIZE", // RET_GETDIBSIZE
  514. "GETDIBFLAGS", // RET_GETDIBFLAGS
  515. "SETDIBSEL", // RET_SETDIBSEL
  516. "FREEDIBSEL", // RET_FREEDIBSEL
  517. };
  518. #endif
  519. register PTD ptd;
  520. register PVDMFRAME pFrame;
  521. register PCBVDMFRAME pCBFrame;
  522. WORD wAX;
  523. BOOL fComDlgSync = FALSE;
  524. INT cStackAlloc16;
  525. VPVOID vpCBStack; // See NOTES in walloc16.c\stackalloc16()
  526. USHORT SaveIp;
  527. #ifdef DEBUG
  528. VPVOID vpStackT;
  529. #endif
  530. WOW32ASSERT(iRetID != RET_RETURN && iRetID != RET_DEBUGRETURN);
  531. ptd = CURRENTPTD();
  532. // ssync 16-bit & 32-bit common dialog structs (see wcommdlg.c)
  533. if(ptd->CommDlgTd) {
  534. // only ssync for stuff that might actually callback into the app
  535. // ie. we don't need to ssync every time wow32 calls GlobalLock16
  536. switch(iRetID) {
  537. case RET_WNDPROC: // try to get these in a most frequently
  538. case RET_HOOKPROC: // used order
  539. case RET_WINSOCKBLOCKHOOK:
  540. case RET_ENUMFONTPROC:
  541. case RET_ENUMWINDOWPROC:
  542. case RET_ENUMOBJPROC:
  543. case RET_ENUMPROPSPROC:
  544. case RET_LINEDDAPROC:
  545. case RET_GRAYSTRINGPROC:
  546. case RET_SETWORDBREAKPROC:
  547. case RET_SETABORTPROC:
  548. // Note: This call can invalidate flat ptrs to 16-bit mem
  549. Ssync_WOW_CommDlg_Structs(ptd->CommDlgTd, w32to16, 0);
  550. fComDlgSync = TRUE; // set this for return ssync
  551. break;
  552. default:
  553. break;
  554. }
  555. }
  556. GETFRAMEPTR(ptd->vpStack, pFrame);
  557. // Just making sure that this thread matches the current 16-bit task
  558. WOW32ASSERT((pFrame->wTDB == ptd->htask16) ||
  559. (ptd->dwFlags & TDF_IGNOREINPUT) ||
  560. (ptd->htask16 == 0));
  561. // set up the callback stack frame from the correct location
  562. // & make it word aligned.
  563. // if stackalloc16() hasn't been called since the app called into wow32
  564. if (ptd->cStackAlloc16 == 0) {
  565. vpCBStack = ptd->vpStack;
  566. ptd->vpCBStack = (ptd->vpStack - sizeof(CBVDMFRAME)) & (~0x1);
  567. }
  568. else {
  569. vpCBStack = ptd->vpCBStack;
  570. ptd->vpCBStack = (ptd->vpCBStack - sizeof(CBVDMFRAME)) & (~0x1);
  571. }
  572. GETFRAMEPTR(ptd->vpCBStack, (PVDMFRAME)pCBFrame);
  573. pCBFrame->vpStack = ptd->vpStack;
  574. pCBFrame->wRetID = (WORD)iRetID;
  575. pCBFrame->wTDB = pFrame->wTDB;
  576. pCBFrame->wLocalBP = pFrame->wLocalBP;
  577. // save the current context stackalloc16() count and set the count to
  578. // 0 for the next context. This will force ptd->vpCBStack to be calc'd
  579. // correctly in any future calls to stackalloc16() if the app callsback
  580. // into WOW
  581. cStackAlloc16 = ptd->cStackAlloc16;
  582. ptd->cStackAlloc16 = 0;
  583. #ifdef DEBUG
  584. // Save
  585. vpStackT = ptd->vpStack;
  586. #endif
  587. if (pParm16)
  588. RtlCopyMemory(&pCBFrame->Parm16, pParm16, sizeof(PARM16));
  589. //if (vpfnProc) // cheaper to just do it
  590. STOREDWORD(pCBFrame->vpfnProc, vpfnProc);
  591. wAX = HIWORD(ptd->vpStack); // Put SS in AX register for callback
  592. if ( iRetID == RET_WNDPROC ) {
  593. if ( pParm16->WndProc.hInst )
  594. wAX = pParm16->WndProc.hInst | 1;
  595. }
  596. pCBFrame->wAX = wAX; // Use this AX for the callback
  597. //
  598. // Semi-slimy way we pass byte count of arguments into this function
  599. // for generic callbacks (WOWCallback16).
  600. //
  601. if (RET_WOWCALLBACK16 == iRetID) {
  602. pCBFrame->wGenUse1 = (WORD)(DWORD)*pvpReturn;
  603. }
  604. #ifdef DEBUG
  605. if (iRetID == RET_WNDPROC) {
  606. LOGDEBUG(9,("%04X Calling WIN16 WNDPROC(%08lx:%04x,%04x,%04x,%04x,%04x)\n",
  607. pFrame->wTDB,
  608. vpfnProc,
  609. pParm16->WndProc.hwnd,
  610. pParm16->WndProc.wMsg,
  611. pParm16->WndProc.wParam,
  612. HIWORD(pParm16->WndProc.lParam),
  613. LOWORD(pParm16->WndProc.lParam)
  614. )
  615. );
  616. } else if (iRetID == RET_HOOKPROC) {
  617. LOGDEBUG(9,("%04X Calling WIN16 HOOKPROC(%08lx: %04x,%04x,%04x,%04x)\n",
  618. pFrame->wTDB,
  619. vpfnProc,
  620. pParm16->HookProc.nCode,
  621. pParm16->HookProc.wParam,
  622. HIWORD(pParm16->HookProc.lParam),
  623. LOWORD(pParm16->HookProc.lParam)
  624. )
  625. );
  626. } else {
  627. LOGDEBUG(9,("%04X Calling WIN16 %s(%04x,%04x,%04x)\n",
  628. pFrame->wTDB,
  629. apszCallBacks[iRetID],
  630. pParm16->WndProc.wParam,
  631. HIWORD(pParm16->WndProc.lParam),
  632. LOWORD(pParm16->WndProc.lParam)
  633. )
  634. );
  635. }
  636. #endif
  637. FREEVDMPTR(pFrame);
  638. FLUSHVDMPTR(ptd->vpCBStack, sizeof(CBVDMFRAME), pCBFrame);
  639. FREEVDMPTR(pCBFrame);
  640. // Set up to use the right 16-bit stack for this thread
  641. SETVDMSTACK(ptd->vpCBStack);
  642. //
  643. // do the callback!
  644. //
  645. // Time to get the IEU running task-time code again
  646. SaveIp = getIP();
  647. host_simulate();
  648. setIP(SaveIp);
  649. ptd->vpStack = VDMSTACK();
  650. // after return from callback ptd->vpStack will point to PCBVDMFRAME
  651. ptd->vpCBStack = ptd->vpStack;
  652. // reset the stackalloc16() count back to this context
  653. ptd->cStackAlloc16 = cStackAlloc16;
  654. GETFRAMEPTR(ptd->vpCBStack, (PVDMFRAME)pCBFrame);
  655. // Just making sure that this thread matches the current 16-bit task
  656. WOW32ASSERT((pCBFrame->wTDB == ptd->htask16) ||
  657. (ptd->htask16 == 0));
  658. if (pvpReturn) {
  659. LOW(*pvpReturn) = pCBFrame->wAX;
  660. HIW(*pvpReturn) = pCBFrame->wDX;
  661. }
  662. switch(iRetID) {
  663. case RET_GLOBALLOCK:
  664. case RET_LOCKRESOURCE:
  665. if(pParm16) {
  666. pParm16->WndProc.lParam =
  667. pCBFrame->wGenUse2 | (LONG)pCBFrame->wGenUse1 << 16;
  668. }
  669. break;
  670. case RET_GLOBALALLOCLOCK:
  671. if(pParm16) {
  672. pParm16->WndProc.wParam = pCBFrame->wGenUse1;
  673. }
  674. break;
  675. case RET_FINDRESOURCE:
  676. if(pParm16) {
  677. pParm16->WndProc.lParam = (ULONG)pCBFrame->wGenUse1;
  678. }
  679. break;
  680. } // end switch
  681. LOGDEBUG(9,("%04X WIN16 %s returning: %lx\n",
  682. pCBFrame->wTDB, apszCallBacks[iRetID], (pvpReturn) ? *pvpReturn : 0));
  683. // restore the stack to its original value.
  684. // ie. fake the 'pop' of callback stack by resetting the vpStack
  685. // to its original value. The ss:sp will actually be updated when
  686. // the 'api thunk' returns.
  687. // consistency check
  688. WOW32ASSERT(pCBFrame->vpStack == vpStackT);
  689. // restore the stack & callback frame ptrs to original values
  690. ptd->vpStack = pCBFrame->vpStack;
  691. ptd->vpCBStack = vpCBStack;
  692. // ssync 16-bit & 32-bit common dialog structs (see wcommdlg.c)
  693. if(fComDlgSync) {
  694. // Note: This call can invalidate flat ptrs to 16-bit mem
  695. Ssync_WOW_CommDlg_Structs(ptd->CommDlgTd, w16to32, 0);
  696. }
  697. FREEVDMPTR(pCBFrame);
  698. return TRUE;
  699. }