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.

4296 lines
128 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: thop16.cxx
  7. //
  8. // Contents: Thop implementations for 16->32
  9. //
  10. // History: 22-Feb-94 DrewB Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "headers.cxx"
  14. #pragma hdrstop
  15. #include <ole2.h>
  16. #include <valid.h>
  17. #include <string.h>
  18. #include "struct16.hxx"
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: EXECUTE_THOP1632, public
  22. //
  23. // Synopsis: Debugging version of thop dispatch routine
  24. //
  25. // Arguments: [pti] - Thunking info
  26. //
  27. // Returns: Appropriate status
  28. //
  29. // History: 24-Feb-94 DrewB Created
  30. //
  31. //----------------------------------------------------------------------------
  32. #if DBG == 1
  33. DWORD EXECUTE_THOP1632(THUNKINFO *pti)
  34. {
  35. thkDebugOut((DEB_THOPS, "%sIn ExThop1632: %s (0x%02X), s16 %p, s32 %p\n",
  36. NestingLevelString(),
  37. ThopName(*pti->pThop), *pti->pThop, pti->s16.pbCurrent,
  38. pti->s32.pbCurrent));
  39. DebugIncrementNestingLevel();
  40. // Local variable
  41. DWORD dwRet;
  42. // Sanity check
  43. thkAssert((*pti->pThop & THOP_OPMASK) < THOP_LASTOP);
  44. dwRet = (*aThopFunctions1632[*((pti)->pThop) & THOP_OPMASK])(pti);
  45. DebugDecrementNestingLevel();
  46. thkDebugOut((DEB_THOPS, "%sOut ExThop1632\n", NestingLevelString()));
  47. return(dwRet);
  48. }
  49. #endif
  50. #if DBG == 1
  51. DWORD EXECUTE_ENUMTHOP1632(THUNKINFO *pti)
  52. {
  53. thkDebugOut((DEB_THOPS, "%sIn ExEnumThop1632: %s (0x%02X), s16 %p, s32 %p\n",
  54. NestingLevelString(),
  55. EnumThopName(*pti->pThop), *pti->pThop, pti->s16.pbCurrent,
  56. pti->s32.pbCurrent));
  57. DebugIncrementNestingLevel();
  58. // Local variable
  59. DWORD dwRet;
  60. dwRet = (*aThopEnumFunctions1632[*(pti)->pThop])(pti);
  61. DebugDecrementNestingLevel();
  62. thkDebugOut((DEB_THOPS, "%sOut ExEnumThop1632\n", NestingLevelString()));
  63. return(dwRet);
  64. }
  65. #endif
  66. // Generated by the tool, in tc1632.cxx
  67. DWORD ThunkCall1632( THUNKINFO * );
  68. //+---------------------------------------------------------------------------
  69. //
  70. // Function: FixedThopHandler, public
  71. //
  72. // Synopsis: Generic function which handles the high-level details
  73. // of thop execution for thops that operate on known-size
  74. // data
  75. //
  76. // Arguments: [pti] - Thunking state information
  77. // [thop] - Thop being executed
  78. // [cb16] - 16-bit size
  79. // [pfn1632] - 16->32 conversion routine
  80. // [cb32] - 32-bit size
  81. // [pfn3216] - 32->16 conversion routine
  82. //
  83. // Returns: Appropriate status code
  84. //
  85. // History: 05-Apr-94 DrewB Created
  86. //
  87. // Notes: Automatically increments pThop
  88. //
  89. //----------------------------------------------------------------------------
  90. DWORD FixedThopHandler1632(THUNKINFO *pti,
  91. THOP thop,
  92. UINT cb16,
  93. FIXEDHANDLERROUTINE pfn1632,
  94. UINT cb32,
  95. FIXEDHANDLERROUTINE pfn3216)
  96. {
  97. DWORD dwResult;
  98. VPVOID vp16;
  99. BYTE *pb16;
  100. BYTE *pb32;
  101. if ((thop & (THOP_IN | THOP_OUT)) != 0)
  102. {
  103. pb32 = NULL;
  104. GET_STACK16(pti, vp16, VPVOID);
  105. if ( vp16 != 0 )
  106. {
  107. pb16 = (BYTE *)ValidatePtr16(pti, vp16, cb16, thop);
  108. if (pb16 != NULL)
  109. {
  110. pb32 = (BYTE *)STACKALLOC32(cb32);
  111. if (pb32 == NULL)
  112. {
  113. pti->scResult = E_OUTOFMEMORY;
  114. }
  115. else if ((thop & THOP_IN) != 0)
  116. {
  117. (pfn1632)(pb16, pb32, cb16, cb32);
  118. }
  119. WOWRELVDMPTR(vp16);
  120. }
  121. }
  122. TO_STACK32(pti, pb32, BYTE *);
  123. pti->pThop++;
  124. dwResult = EXECUTE_THOP1632(pti);
  125. if ((thop & THOP_OUT) != 0 && vp16 != 0)
  126. {
  127. pb16 = (BYTE *)WOWFIXVDMPTR(vp16, cb16);
  128. if (SUCCEEDED(dwResult))
  129. {
  130. (pfn3216)(pb32, pb16, cb32, cb16);
  131. }
  132. else if ((thop & THOP_IN) == 0)
  133. {
  134. // Zero out-only parameters on failure
  135. memset(pb16, 0, cb16);
  136. }
  137. WOWRELVDMPTR(vp16);
  138. }
  139. if (pb32 != NULL)
  140. {
  141. STACKFREE32(pb32, cb32);
  142. }
  143. }
  144. else
  145. {
  146. (pfn1632)(PTR_STACK16(&pti->s16, cb16), PTR_STACK32(&pti->s32),
  147. cb16, cb32);
  148. SKIP_STACK16(&pti->s16, cb16);
  149. SKIP_STACK32(&pti->s32, cb32);
  150. pti->pThop++;
  151. dwResult = EXECUTE_THOP1632(pti);
  152. }
  153. return dwResult;
  154. }
  155. //-----------------------------------------------------------------------------
  156. //
  157. // Handler-based thunks
  158. //
  159. // These thunks use the fixed-size generic thop handler to do their work
  160. //
  161. //-----------------------------------------------------------------------------
  162. // Handle straight copy
  163. DWORD Thop_Copy_1632(THUNKINFO *pti)
  164. {
  165. THOP thopSize;
  166. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_COPY);
  167. thopSize = *++pti->pThop;
  168. return FixedThopHandler1632(pti,
  169. *(pti->pThop-1),
  170. thopSize, FhCopyMemory,
  171. thopSize, FhCopyMemory);
  172. }
  173. DWORD Thop_ShortToLong_1632(THUNKINFO *pti)
  174. {
  175. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SHORTLONG);
  176. return FixedThopHandler1632(pti,
  177. *pti->pThop,
  178. sizeof(SHORT), FhShortToLong,
  179. sizeof(LONG), FhLongToShort);
  180. }
  181. DWORD Thop_WordToDword_1632(THUNKINFO *pti)
  182. {
  183. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_WORDDWORD);
  184. return FixedThopHandler1632(pti,
  185. *pti->pThop,
  186. sizeof(WORD), FhWordToDword,
  187. sizeof(DWORD), FhDwordToWord);
  188. }
  189. DWORD Thop_GdiHandle_1632(THUNKINFO *pti)
  190. {
  191. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HGDI);
  192. return FixedThopHandler1632(pti,
  193. *pti->pThop,
  194. sizeof(HAND16), FhGdiHandle1632,
  195. sizeof(HANDLE), FhGdiHandle3216);
  196. }
  197. DWORD Thop_UserHandle_1632(THUNKINFO *pti)
  198. {
  199. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HUSER);
  200. return FixedThopHandler1632(pti,
  201. *pti->pThop,
  202. sizeof(HAND16), FhUserHandle1632,
  203. sizeof(HANDLE), FhUserHandle3216);
  204. }
  205. DWORD Thop_HACCEL_1632(THUNKINFO *pti)
  206. {
  207. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HACCEL);
  208. return FixedThopHandler1632(pti,
  209. *pti->pThop,
  210. sizeof(HAND16), FhHaccel1632,
  211. sizeof(HANDLE), FhHaccel3216);
  212. }
  213. DWORD Thop_HTASK_1632(THUNKINFO *pti)
  214. {
  215. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HTASK);
  216. return FixedThopHandler1632(pti,
  217. *pti->pThop,
  218. sizeof(HAND16), FhHtask1632,
  219. sizeof(HANDLE), FhHtask3216);
  220. }
  221. DWORD Thop_HRESULT_1632( THUNKINFO *pti )
  222. {
  223. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_HRESULT);
  224. return FixedThopHandler1632(pti,
  225. *pti->pThop,
  226. sizeof(HRESULT), FhHresult1632,
  227. sizeof(HRESULT), FhHresult3216);
  228. }
  229. DWORD Thop_NULL_1632(THUNKINFO *pti)
  230. {
  231. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_NULL);
  232. return FixedThopHandler1632(pti,
  233. *pti->pThop,
  234. sizeof(void *), FhNull,
  235. sizeof(void *), FhNull);
  236. }
  237. DWORD Thop_RECT_1632( THUNKINFO *pti )
  238. {
  239. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_RECT);
  240. return FixedThopHandler1632(pti,
  241. *pti->pThop,
  242. sizeof(RECT16), FhRect1632,
  243. sizeof(RECT), FhRect3216);
  244. }
  245. DWORD Thop_BINDOPTS_1632( THUNKINFO *pti )
  246. {
  247. VPVOID vpbo16;
  248. BIND_OPTS UNALIGNED *pbo;
  249. UINT cb;
  250. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_BINDOPTS);
  251. PEEK_STACK16(pti, vpbo16, VPVOID);
  252. pbo = (BIND_OPTS UNALIGNED *)GetReadPtr16(pti, vpbo16, sizeof(BIND_OPTS));
  253. if (pbo != NULL)
  254. {
  255. cb = pbo->cbStruct;
  256. WOWRELVDMPTR(vpbo16);
  257. }
  258. else
  259. {
  260. // Doesn't really matter, since pti->scResult was set to error
  261. // by GetReadPtr16
  262. cb = sizeof(BIND_OPTS);
  263. }
  264. return FixedThopHandler1632(pti,
  265. *pti->pThop,
  266. cb, FhCopyMemory,
  267. cb, FhCopyMemory);
  268. }
  269. DWORD Thop_SIZE_1632( THUNKINFO *pti )
  270. {
  271. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SIZE);
  272. return FixedThopHandler1632(pti,
  273. *pti->pThop,
  274. sizeof(SIZE16), FhSize1632,
  275. sizeof(SIZE), FhSize3216);
  276. }
  277. DWORD Thop_MSG_1632( THUNKINFO *pti )
  278. {
  279. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_MSG);
  280. return FixedThopHandler1632(pti,
  281. *pti->pThop,
  282. sizeof(MSG16), FhMsg1632,
  283. sizeof(MSG), FhMsg3216);
  284. }
  285. //+---------------------------------------------------------------------------
  286. //
  287. // Function: Thop_ERROR_1632, public
  288. //
  289. // Synopsis: Any Thop type which should just fail with an error
  290. // should go be directed here.
  291. //
  292. // Arguments: [pti] - Thunk state information
  293. //
  294. // Returns: Appropriate status code
  295. //
  296. // History: 23-Feb-94 BobDay Created
  297. //
  298. //----------------------------------------------------------------------------
  299. DWORD Thop_ERROR_1632 ( THUNKINFO *pti )
  300. {
  301. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_ERROR);
  302. thkAssert( FALSE && "Hey we hit an ERROR Thop in 16->32" );
  303. return (DWORD)E_UNEXPECTED;
  304. }
  305. //+---------------------------------------------------------------------------
  306. //
  307. // Function: ThunkInString1632, public
  308. //
  309. // Synopsis: Converts an in-parameter string
  310. //
  311. // Arguments: [pti] - Thunk state information
  312. //
  313. // Returns: Appropriate status code
  314. //
  315. // History: 24-Aug-94 DrewB Created
  316. //
  317. //----------------------------------------------------------------------------
  318. DWORD ThunkInString1632(THUNKINFO *pti)
  319. {
  320. DWORD dwResult;
  321. VPSTR vpstr;
  322. LPOLESTR lpstrDest;
  323. OLECHAR *ptcStackText;
  324. dwResult = (DWORD)S_OK;
  325. ptcStackText = NULL;
  326. GET_STACK16(pti, vpstr, VPSTR);
  327. if (vpstr == 0)
  328. {
  329. lpstrDest = NULL;
  330. }
  331. else
  332. {
  333. ptcStackText = (OLECHAR *)STACKALLOC32(CWCSTRINGPREALLOC*
  334. sizeof(OLECHAR));
  335. if (ptcStackText == NULL)
  336. {
  337. pti->scResult = E_OUTOFMEMORY;
  338. }
  339. else
  340. {
  341. lpstrDest = Convert_VPSTR_to_LPOLESTR( pti, vpstr, ptcStackText,
  342. CWCSTRINGPREALLOC );
  343. }
  344. }
  345. thkDebugOut((DEB_ARGS, "In1632 LPSTR: %p -> %p '%ws'\n",
  346. vpstr, lpstrDest, lpstrDest));
  347. TO_STACK32(pti, lpstrDest, LPOLESTR );
  348. pti->pThop++;
  349. dwResult = EXECUTE_THOP1632(pti);
  350. if (lpstrDest != NULL)
  351. {
  352. Convert_VPSTR_to_LPOLESTR_free( ptcStackText, lpstrDest );
  353. }
  354. if (ptcStackText != NULL)
  355. {
  356. STACKFREE32(ptcStackText, CWCSTRINGPREALLOC*sizeof(OLECHAR));
  357. }
  358. return( dwResult );
  359. }
  360. //+---------------------------------------------------------------------------
  361. //
  362. // Function: Thop_LPSTR_1632, public
  363. //
  364. // Synopsis: Converts 16-bit LPSTR to 32-bit LPSTR pointer
  365. //
  366. // Arguments: [pti] - Thunk state information
  367. //
  368. // Returns: Appropriate status code
  369. //
  370. // History: 23-Feb-94 BobDay Created
  371. //
  372. //----------------------------------------------------------------------------
  373. DWORD Thop_LPSTR_1632( THUNKINFO *pti )
  374. {
  375. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_LPSTR);
  376. //
  377. // We have only input LPSTRs
  378. //
  379. thkAssert( (*pti->pThop & THOP_IOMASK) == THOP_IN &&
  380. "LPSTR must be input only!" );
  381. return ThunkInString1632(pti);
  382. }
  383. //+---------------------------------------------------------------------------
  384. //
  385. // Function: ConvertTaskString3216, public
  386. //
  387. // Synopsis: Converts a task-memory string
  388. //
  389. // Arguments: [pti] - Thunk info
  390. // [pos32] - String
  391. // [vpstrPreAlloc] - Preallocated string or NULL
  392. // [cchPreAlloc] - Preallocated size or zero
  393. // [pvpstr16] - String
  394. //
  395. // Returns: Appropriate status code
  396. //
  397. // Modifies: [pti]
  398. // [pvpstr16]
  399. //
  400. // History: 14-May-94 DrewB Created
  401. //
  402. // Notes: Frees preallocation if successful and:
  403. // Name is too large or
  404. // Name is NULL
  405. //
  406. // Always frees source string if non-zero and valid
  407. //
  408. //----------------------------------------------------------------------------
  409. SCODE ConvertTaskString3216(THUNKINFO *pti,
  410. LPOLESTR pos32,
  411. VPSTR vpstrPreAlloc,
  412. UINT cchPreAlloc,
  413. VPSTR UNALIGNED *pvpstr16)
  414. {
  415. VPVOID vpstr16;
  416. UINT cch;
  417. SCODE sc;
  418. sc = S_OK;
  419. if (pos32 == NULL)
  420. {
  421. vpstr16 = 0;
  422. }
  423. else
  424. {
  425. if (IsBadStringPtrW(pos32, CCHMAXSTRING))
  426. {
  427. sc = E_INVALIDARG;
  428. }
  429. else
  430. {
  431. cch = lstrlenW(pos32)+1;
  432. if (cch > cchPreAlloc)
  433. {
  434. // Our prealloc buffer is too small, so try and get a
  435. // new one
  436. // Allow for each Unicode character to take two
  437. // bytes in case of multibyte expansion
  438. vpstr16 = (VPSTR)TaskMalloc16( cch*2 );
  439. if (vpstr16 == 0)
  440. {
  441. sc = E_OUTOFMEMORY;
  442. }
  443. }
  444. else
  445. {
  446. vpstr16 = vpstrPreAlloc;
  447. }
  448. if (SUCCEEDED(sc))
  449. {
  450. sc = Convert_LPOLESTR_to_VPSTR(pos32, vpstr16, cch, cch*2);
  451. if (FAILED(sc) && vpstr16 != vpstrPreAlloc)
  452. {
  453. TaskFree16(vpstr16);
  454. }
  455. }
  456. TaskFree32(pos32);
  457. }
  458. }
  459. if (SUCCEEDED(sc))
  460. {
  461. // If there was a preallocated string we didn't use,
  462. // free it
  463. if (vpstrPreAlloc != 0 && vpstrPreAlloc != vpstr16)
  464. {
  465. TaskFree16(vpstrPreAlloc);
  466. }
  467. *pvpstr16 = vpstr16;
  468. }
  469. return sc;
  470. }
  471. //+---------------------------------------------------------------------------
  472. //
  473. // Function: ThunkOutString1632, public
  474. //
  475. // Synopsis: Converts an out param string or filename
  476. //
  477. // Arguments: [pti] - Thunk state information
  478. // [fFile] - Filename or plain string
  479. //
  480. // Returns: Appropriate status code
  481. //
  482. // History: 24-Aug-94 DrewB Created
  483. //
  484. //----------------------------------------------------------------------------
  485. DWORD ThunkOutString1632(THUNKINFO *pti,
  486. BOOL fFile)
  487. {
  488. DWORD dwResult;
  489. VPVOID vpvpstr16;
  490. VPSTR vpstr16;
  491. VPSTR UNALIGNED *lpvpstr16;
  492. LPOLESTR *lplpstr32;
  493. LPOLESTR lpstr = NULL;
  494. GET_STACK16(pti, vpvpstr16, VPSTR);
  495. lplpstr32 = NULL;
  496. if ( vpvpstr16 != 0 )
  497. {
  498. lpvpstr16 = (VPSTR UNALIGNED *)GetWritePtr16(pti, vpvpstr16,
  499. sizeof(VPSTR));
  500. if ( lpvpstr16 != NULL )
  501. {
  502. WOWRELVDMPTR(vpvpstr16);
  503. lplpstr32 = &lpstr;
  504. vpstr16 = (VPSTR)TaskMalloc16(CBSTRINGPREALLOC);
  505. if (vpstr16 == 0)
  506. {
  507. pti->scResult = E_OUTOFMEMORY;
  508. }
  509. }
  510. }
  511. TO_STACK32(pti, lplpstr32, LPOLESTR FAR *);
  512. pti->pThop++;
  513. dwResult = EXECUTE_THOP1632(pti);
  514. if ( lplpstr32 != NULL )
  515. {
  516. if ( SUCCEEDED(dwResult) )
  517. {
  518. SCODE sc;
  519. if (fFile)
  520. {
  521. UINT cch;
  522. // The string pointed to by lpstr is ours so we
  523. // can do the long->short conversion in place
  524. // without worrying about trashing the memory
  525. // The short path name should always be able
  526. // to fit in the long path name's buffer since
  527. // the file names that we are thunking are always
  528. // absolute paths
  529. cch = lstrlenW(lpstr)+1;
  530. // Ignore failures; if we can't convert the name
  531. // then we simply pass on what we were given
  532. GetShortPathName(lpstr, lpstr, cch);
  533. }
  534. sc = ConvertTaskString3216(pti, lpstr, vpstr16,
  535. CWCSTRINGPREALLOC, &vpstr16);
  536. if (FAILED(sc))
  537. {
  538. dwResult = sc;
  539. }
  540. }
  541. if (FAILED(dwResult))
  542. {
  543. TaskFree16(vpstr16);
  544. vpstr16 = 0;
  545. }
  546. lpvpstr16 = FIXVDMPTR( vpvpstr16, VPSTR );
  547. *lpvpstr16 = vpstr16;
  548. #if DBG==1
  549. thkDebugOut((DEB_ARGS, "%sOut1632 LPLPSTR: %p -> %p '%s'\n",
  550. NestingLevelString(), lpstr, vpstr16,
  551. vpstr16 != 0 ? WOWFIXVDMPTR(vpstr16, 0) : "<null>"));
  552. if (vpstr16 != 0)
  553. {
  554. WOWRELVDMPTR(vpstr16);
  555. }
  556. #endif
  557. RELVDMPTR( vpvpstr16 );
  558. }
  559. else
  560. {
  561. thkDebugOut((DEB_ARGS, "Out1632 LPLPSTR NULL\n"));
  562. }
  563. return( dwResult );
  564. }
  565. //+---------------------------------------------------------------------------
  566. //
  567. // Function: Thop_LPLPSTR_1632, public
  568. //
  569. // Synopsis: Converts 32-bit LPSTR to 16-bit LPSTR pointer
  570. //
  571. // Arguments: [pti] - Thunk state information
  572. //
  573. // Returns: Appropriate status code
  574. //
  575. // History: 25-Feb-94 BobDay Created
  576. //
  577. //----------------------------------------------------------------------------
  578. DWORD Thop_LPLPSTR_1632( THUNKINFO *pti )
  579. {
  580. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_LPLPSTR);
  581. //
  582. // We don't have anything but unmodified LPLPSTRs
  583. //
  584. thkAssert( (*pti->pThop & THOP_IOMASK) == 0 &&
  585. "LPLPSTR must be unmodified only!" );
  586. return ThunkOutString1632(pti, FALSE);
  587. }
  588. //+---------------------------------------------------------------------------
  589. //
  590. // Function: Thop_BUFFER_1632, public
  591. //
  592. // Synopsis: Converts 16-bit block of memory to 32-bit block of memory
  593. //
  594. // Arguments: [pti] - Thunk state information
  595. //
  596. // Returns: Appropriate status code
  597. //
  598. // History: 25-Feb-94 BobDay Created
  599. // 14-Mar-95 KentCe Buffer copy not required for Win95.
  600. //
  601. // Notes: WARNING! WARNING! WARNING! For an out parameter this expects
  602. // three parameters on the stack in the following format and order:
  603. // VOID * pointer to buffer
  604. // DWORD count of bytes in buffer
  605. // DWORD * count of bytes returned in the buffer
  606. //
  607. //----------------------------------------------------------------------------
  608. #define WATCH_VALUE 0xfef1f0
  609. DWORD Thop_BUFFER_1632( THUNKINFO *pti )
  610. {
  611. DWORD dwResult;
  612. BOOL fThopInput;
  613. BOOL fThopOutput;
  614. VPVOID vp16;
  615. LPVOID lp16;
  616. LPVOID lp32;
  617. DWORD dwCount;
  618. VPVOID vp16CountOut;
  619. DWORD dwCountOut32 = 0;
  620. DWORD * pdwCountOut32 = &dwCountOut32;
  621. #if DBG == 1
  622. DWORD dwWatch;
  623. #endif
  624. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_BUFFER);
  625. fThopInput = IS_THOP_IN(pti);
  626. fThopOutput = IS_THOP_OUT(pti);
  627. //
  628. // We only have in and out BUFFER thops
  629. //
  630. thkAssert((fThopInput || fThopOutput)
  631. && (fThopInput != fThopOutput)
  632. && "BUFFER must be in or out only!" );
  633. GET_STACK16(pti, vp16, VPVOID);
  634. GET_STACK16(pti, dwCount, DWORD);
  635. if (fThopOutput)
  636. {
  637. // Get the pointer to the returned value off the stack
  638. GET_STACK16(pti, vp16CountOut, VPVOID);
  639. }
  640. lp32 = NULL;
  641. if (vp16 == 0)
  642. {
  643. // lp32 is already NULL
  644. }
  645. else if (dwCount == 0)
  646. {
  647. // If the count is zero then we can pass any valid 32-bit
  648. // pointer
  649. #if DBG == 1
  650. // In debug, make sure that no data is written back to the
  651. // memory we pass on
  652. dwWatch = WATCH_VALUE;
  653. lp32 = &dwWatch;
  654. #else
  655. lp32 = &dwResult;
  656. #endif
  657. }
  658. else
  659. {
  660. lp16 = ValidatePtr16(pti, vp16, dwCount, *pti->pThop);
  661. if ( lp16 != NULL )
  662. {
  663. lp32 = (LPVOID)CoTaskMemAlloc( dwCount );
  664. if ( lp32 == NULL )
  665. {
  666. pti->scResult = E_OUTOFMEMORY;
  667. }
  668. else
  669. {
  670. if ( fThopInput )
  671. {
  672. memcpy( lp32, lp16, dwCount );
  673. }
  674. }
  675. WOWRELVDMPTR(vp16);
  676. }
  677. }
  678. thkDebugOut((DEB_ARGS, "1632 BUFFER: %p -> %p, %u\n",
  679. vp16, lp32, dwCount));
  680. TO_STACK32(pti, lp32, LPVOID );
  681. TO_STACK32(pti, dwCount, DWORD );
  682. if (fThopOutput)
  683. {
  684. TO_STACK32(pti, pdwCountOut32, LPVOID );
  685. }
  686. pti->pThop++;
  687. dwResult = EXECUTE_THOP1632(pti);
  688. if (fThopOutput)
  689. {
  690. // If the pointer in sixteen bit land is non-null then return the
  691. // count of bytes written to the buffer.
  692. DWORD UNALIGNED *lpdw16 = (DWORD UNALIGNED *)
  693. ValidatePtr16(pti, vp16CountOut, sizeof(DWORD), *pti->pThop);
  694. if (lpdw16 != NULL)
  695. {
  696. *lpdw16 = dwCountOut32;
  697. WOWRELVDMPTR(vp16CountOut);
  698. }
  699. if ( SUCCEEDED(dwResult) )
  700. {
  701. if (dwCountOut32 > 0 && vp16 != 0)
  702. {
  703. lp16 = (LPVOID)WOWFIXVDMPTR( vp16, dwCountOut32 );
  704. memcpy( lp16, lp32, dwCountOut32 );
  705. WOWRELVDMPTR(vp16);
  706. }
  707. }
  708. }
  709. #if DBG == 1
  710. if (lp32 != NULL && dwCount == 0)
  711. {
  712. thkAssert(dwWatch == WATCH_VALUE);
  713. }
  714. #endif
  715. //
  716. // Now free the buffer
  717. //
  718. if ( lp32 != NULL && dwCount > 0 )
  719. {
  720. CoTaskMemFree( lp32 );
  721. }
  722. return( dwResult );
  723. }
  724. //+---------------------------------------------------------------------------
  725. //
  726. // Function: Thop_SNB_1632, public
  727. //
  728. // Synopsis: Converts 16-bit SNB to 32-bit SNB pointer
  729. //
  730. // Arguments: [pti] - Thunk state information
  731. //
  732. // Returns: Appropriate status code
  733. //
  734. // History: 23-Feb-94 BobDay Created
  735. //
  736. //----------------------------------------------------------------------------
  737. DWORD Thop_SNB_1632( THUNKINFO *pti )
  738. {
  739. DWORD dwResult;
  740. BOOL fThopInput;
  741. BOOL fThopOutput;
  742. VPVOID snb16;
  743. VPSTR *lpvpstr;
  744. VPSTR UNALIGNED *lpvpstrTemp;
  745. VPSTR vpstr;
  746. SNB snb32;
  747. UINT cStr;
  748. UINT cStrTemp;
  749. LPOLESTR *lplpstr;
  750. UINT cbStrings;
  751. OLECHAR *pocStr;
  752. LPSTR lpstr16;
  753. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SNB);
  754. fThopInput = IS_THOP_IN(pti);
  755. fThopOutput = IS_THOP_OUT(pti);
  756. //
  757. // We don't have anything but unmodified SNBs
  758. //
  759. thkAssert( !fThopInput && !fThopOutput && "SNB must be unmodified only!" );
  760. GET_STACK16(pti, snb16, VPVOID);
  761. snb32 = NULL;
  762. if ( snb16 != 0 )
  763. {
  764. //
  765. // Count the strings in the 16-bit snb
  766. //
  767. lpvpstr = (VPSTR FAR *)GetReadPtr16( pti, snb16, sizeof(VPSTR) );
  768. if ( lpvpstr != 0 )
  769. {
  770. lpvpstrTemp = lpvpstr;
  771. cStr = 0;
  772. cbStrings = 0;
  773. do
  774. {
  775. cStr++;
  776. vpstr = *lpvpstrTemp++;
  777. if ( vpstr == 0 )
  778. {
  779. break;
  780. }
  781. lpstr16 = GetStringPtr16(pti, vpstr, CCHMAXSTRING,
  782. &cStrTemp);
  783. if ( lpstr16 == 0 )
  784. {
  785. WOWRELVDMPTR(snb16);
  786. lpvpstr = NULL;
  787. break; // Leave with snb32 still NULL
  788. }
  789. WOWRELVDMPTR(vpstr);
  790. cbStrings += cStrTemp;
  791. }
  792. while ( TRUE );
  793. }
  794. if ( lpvpstr != NULL )
  795. {
  796. thkDebugOut((DEB_ARGS, "In1632 SNB: %d strings\n", cStr));
  797. //
  798. // Allocate space for the 32-bit snb
  799. //
  800. snb32 = (LPOLESTR FAR *)CoTaskMemAlloc( cStr*sizeof(LPOLESTR) +
  801. cbStrings*sizeof(WCHAR));
  802. if (snb32 == NULL)
  803. {
  804. pti->scResult = E_OUTOFMEMORY;
  805. }
  806. else
  807. {
  808. pocStr = (OLECHAR *)((BYTE *)snb32+cStr*sizeof(LPOLESTR));
  809. //
  810. // Now convert the strings
  811. //
  812. lpvpstrTemp = lpvpstr;
  813. lplpstr = snb32;
  814. cStrTemp = cStr - 1;
  815. while ( cStrTemp > 0 )
  816. {
  817. --cStrTemp;
  818. vpstr = *lpvpstrTemp++;
  819. thkAssert( vpstr != 0 &&
  820. "Loop is processing end of snb\n" );
  821. // Guaranteed to use pocStr as storage since cbStrings is
  822. // large enough to contain all the strings
  823. *lplpstr = Convert_VPSTR_to_LPOLESTR( pti, vpstr,
  824. pocStr, cbStrings );
  825. if (*lplpstr == NULL)
  826. {
  827. CoTaskMemFree(snb32);
  828. snb32 = NULL;
  829. break;
  830. }
  831. #if DBG == 1
  832. thkDebugOut((DEB_ARGS, "In1632 SNB: %p '%s' -> "
  833. "%p '%ws'\n",
  834. vpstr, WOWFIXVDMPTR(vpstr, 0),
  835. *lplpstr, *lplpstr));
  836. WOWRELVDMPTR(vpstr);
  837. #endif
  838. pocStr += lstrlenW(pocStr)+1;
  839. lplpstr++;
  840. }
  841. // Terminate SNB
  842. *lplpstr = NULL;
  843. thkAssert(*lpvpstrTemp == 0);
  844. WOWRELVDMPTR(snb16);
  845. }
  846. }
  847. }
  848. thkDebugOut((DEB_ARGS, "In1632 SNB: %p -> %p\n", snb16, snb32));
  849. TO_STACK32(pti, snb32, SNB );
  850. pti->pThop++;
  851. dwResult = EXECUTE_THOP1632(pti);
  852. //
  853. // Free SNB memory if necessary
  854. //
  855. if ( snb32 != 0 )
  856. {
  857. CoTaskMemFree(snb32);
  858. }
  859. return( dwResult );
  860. }
  861. //+---------------------------------------------------------------------------
  862. //
  863. // Function: ThunkInterface1632, private
  864. //
  865. // Synopsis: Handles interface thunking for THOP_IFACE and
  866. // THOP_IFACEGEN
  867. //
  868. // Arguments: [pti] - Thunking state information
  869. // [iidx] - Interface index or IID
  870. // [thop] - Thop being executed
  871. // [punkOuter] - Controlling IUnknown or NULL
  872. //
  873. // Returns: status code
  874. //
  875. // History: Mar 14,97 Gopalk Rewritten to support aggregation and
  876. // proper thunking of IN/OUT interfaces
  877. //
  878. // Notes: Assumes caller has already adjusted pti->pThop
  879. //----------------------------------------------------------------------------
  880. DWORD ThunkInterface1632(THUNKINFO *pti, IIDIDX iidx, THOP thop, IUnknown *punkOuter)
  881. {
  882. // Local variables
  883. VPVOID vpv;
  884. DWORD dwResult, dwStatus;
  885. IUnknown *punkThis32In;
  886. IUnknown *punkThis32Out;
  887. VPVOID vpvOut;
  888. VPVOID vpvIn;
  889. VPVOID UNALIGNED *pvpvOut;
  890. VPVOID vpvPreAlloc = NULL;
  891. THUNK1632OBJ UNALIGNED *pto;
  892. PROXYHOLDER *pph;
  893. PROXYHOLDER *pAggHolder = NULL;
  894. SAggHolder aggHolderNode;
  895. BOOL bUnlinkAggHolder = FALSE;
  896. BOOL bExtraAddRef;
  897. // Validate the IID of the interface
  898. thkAssert(IIDIDX_IS_IID(iidx) ||
  899. (IIDIDX_INDEX(iidx) >= 0 && IIDIDX_INDEX(iidx) <= THI_COUNT));
  900. // Initialize
  901. dwResult = (DWORD) S_OK;
  902. punkThis32In = NULL;
  903. pph = NULL;
  904. // Retrieve interface pointer
  905. GET_STACK16(pti, vpv, VPVOID);
  906. // Assert invariant
  907. thkAssert(iidx!=THI_COUNT || vpv==NULL);
  908. // Check for valid OUT parameter. It also verifies IN-OUT case as well
  909. if((thop & THOP_OUT) && vpv) {
  910. pvpvOut = (VPVOID UNALIGNED *)GetWritePtr16(pti, vpv, sizeof(VPVOID));
  911. if(!pvpvOut) {
  912. thkDebugOut((DEB_WARN, "WARNING: ThunkInterface1632 - bad pointer %p\n",
  913. vpv));
  914. pti->scResult = E_INVALIDARG;
  915. return (DWORD) E_INVALIDARG;
  916. }
  917. // Check if the interface needs to be thunked IN as well.
  918. // In other words, IN-OUT paramenter case
  919. if(thop & THOP_IN)
  920. vpvIn = *pvpvOut;
  921. else
  922. vpvIn = NULL;
  923. // Release the VMD pointer
  924. WOWRELVDMPTR(vpv);
  925. }
  926. else {
  927. // It must be IN parameter or a NULL OUT parameter
  928. vpvIn = vpv;
  929. }
  930. // Check if interface needs to be thunked IN
  931. if(thop & THOP_IN) {
  932. if (vpvIn) {
  933. // Validate the interface
  934. if(IsValidInterface16(pti, vpvIn)) {
  935. if((thop & THOP_OPMASK) == THOP_IFACENOADDREF) {
  936. // vpvIn represents an interface that is used by the
  937. // 32-bit side without addrefing it.
  938. // Classic example: IOleCacheControl::OnRun
  939. // Aggregate it with the identity of the interface on which
  940. // the current call is being made to ensure that lifetime of proxy
  941. // is controlled by it.
  942. VPVOID vpvThis16;
  943. // Obtain the 16-bit interface on which the current call is
  944. // being made
  945. thkAssert(punkOuter);
  946. vpvThis16 = pti->pThkMgr->LookupProxy1632(punkOuter);
  947. thkAssert(vpvThis16);
  948. // Obtain its holder
  949. pto = FIXVDMPTR(vpvThis16, THUNK1632OBJ);
  950. pph = pto->pphHolder;
  951. thkAssert(pto->punkThis32 == punkOuter);
  952. RELVDMPTR(vpvThis16);
  953. // Assert that holder exists
  954. thkAssert(pph);
  955. }
  956. else {
  957. thkAssert(pph == NULL);
  958. }
  959. if((thop & THOP_OPMASK) == THOP_UNKOUTER) {
  960. // Aggregation is being carried out
  961. // Assert that interface is only being thunked IN
  962. thkAssert(!(thop & THOP_OUT));
  963. thkAssert(iidx == THI_IUnknown);
  964. // Either find the actual 32-bit identity or generate a
  965. // new 32-bit proxy identity for the 16-bit identity
  966. punkThis32In = pti->pThkMgr->CreateOuter32(vpvIn, &pAggHolder, &dwStatus);
  967. aggHolderNode.pph = pAggHolder;
  968. bUnlinkAggHolder = TRUE;
  969. TlsThkLinkAggHolder(&aggHolderNode);
  970. // We use this pAggHolder for proxies of inner unk(s). Since
  971. // we cannot put it in the proxy table (as it is private
  972. // and we do not want other thunk calls to use it), we put
  973. // it in a linked list in the TLS. The holder gets used by
  974. // calls to FindAggregate() when the pUnkInner is being
  975. // thunked out. The holder is revoked from the list when
  976. // the ThunkInterface call for the pUnkOuter unwinds.
  977. }
  978. else {
  979. // Find/Generate the proxy for the 16-bit interface to be thunked IN
  980. bExtraAddRef = FALSE;
  981. if (
  982. (
  983. (pti->pvfn == (VTBLFN) OleIsCurrentClipboard) &&
  984. (TlsThkGetAppCompatFlags() & OACF_WORKSCLIPOBJ)
  985. )
  986. ||
  987. (
  988. (TlsThkGetAppCompatFlags() & OACF_TEXTARTDOBJ) &&
  989. (pti->iidx == THI_IDataAdviseHolder) &&
  990. (iidx == THI_IDataObject) && (pti->dwMethod == 3)
  991. )
  992. ){
  993. bExtraAddRef = TRUE;
  994. }
  995. punkThis32In = pti->pThkMgr->FindProxy3216(NULL, vpvIn, pph,
  996. iidx, bExtraAddRef, &dwStatus);
  997. }
  998. if(punkThis32In) {
  999. thkAssert(!((thop & THOP_OPMASK) == THOP_UNKOUTER) ||
  1000. (dwStatus == FST_CREATED_NEW) ||
  1001. (dwStatus == FST_SHORTCUT));
  1002. }
  1003. else {
  1004. thkDebugOut((DEB_WARN, "WARNING: ThunkInterface1632 - Can't create proxy for %p\n",
  1005. vpvIn));
  1006. pti->scResult = E_OUTOFMEMORY;
  1007. return (DWORD) E_OUTOFMEMORY;
  1008. }
  1009. }
  1010. else {
  1011. thkDebugOut((DEB_WARN, "WARNING: ThunkInterface1632 - invalid interface %p\n",
  1012. vpvIn));
  1013. pti->scResult = E_INVALIDARG;
  1014. return (DWORD) E_INVALIDARG;
  1015. }
  1016. }
  1017. else {
  1018. // No interface to be thunked IN
  1019. punkThis32In = NULL;
  1020. }
  1021. thkDebugOut((DEB_ARGS, "%sIn1632 %s %p -> %p\n",
  1022. NestingLevelString(), IidIdxString(iidx),
  1023. vpvIn, punkThis32In));
  1024. }
  1025. // Check if interface needs to be thunked OUT
  1026. if((thop & THOP_OUT) && vpv) {
  1027. // Preallocate a proxy for the out parameter
  1028. vpvPreAlloc = pti->pThkMgr->CanGetNewProxy1632(iidx);
  1029. if(vpvPreAlloc) {
  1030. // Assert that no interface is being thunked IN for
  1031. // pure OUT parameter case
  1032. thkAssert((thop & THOP_IN) || !punkThis32In);
  1033. // Use a local variable for OUT parameter
  1034. punkThis32Out = punkThis32In;
  1035. // Push the OUT/IN-OUT parameter onto the stack
  1036. TO_STACK32(pti, &punkThis32Out, IUnknown **);
  1037. // Corel Draw 5.0 HACK
  1038. // Some apps seem to call through the OUT parameter in the
  1039. // nested calls before the following call returns
  1040. // Set the temporary proxy's this pointer to point to
  1041. // 32-bit out pointer pushed onto the satck
  1042. pto = FIXVDMPTR(vpvPreAlloc, THUNK1632OBJ);
  1043. pto->punkThis32 = (IUnknown *)&punkThis32Out;
  1044. RELVDMPTR(vpvPreAlloc);
  1045. // Set the 16-bit OUT parameter to the preallocated proxy
  1046. *FIXVDMPTR(vpv, VPVOID) = vpvPreAlloc;
  1047. RELVDMPTR(vpv);
  1048. }
  1049. else {
  1050. thkDebugOut((DEB_WARN, "WARNING: ThunkInterface1632 - Cannot preallocate proxy\n"));
  1051. pti->scResult = E_OUTOFMEMORY;
  1052. dwResult = (DWORD) E_OUTOFMEMORY;
  1053. }
  1054. }
  1055. else
  1056. {
  1057. // Assert invariant
  1058. thkAssert((vpv && punkThis32In) || (!vpv && !punkThis32In));
  1059. TO_STACK32(pti, punkThis32In, IUnknown *);
  1060. }
  1061. if(SUCCEEDED((SCODE)dwResult)) {
  1062. // Execute the next THOP operation
  1063. dwResult = EXECUTE_THOP1632(pti);
  1064. }
  1065. if((thop & THOP_OUT) && vpv) {
  1066. vpvOut = 0;
  1067. if(SUCCEEDED((SCODE)dwResult) && punkThis32Out) {
  1068. // Obtain 16-bit proxy for the 32-bit interface
  1069. if(punkOuter) {
  1070. //Get the holder that was linked into TLS when the pUnkOuter
  1071. //was being thunked in.
  1072. pAggHolder = (TlsThkGetAggHolder())->pph;
  1073. vpvOut = pti->pThkMgr->FindAggregate1632(vpvPreAlloc, punkOuter,
  1074. punkThis32Out, iidx, pAggHolder,
  1075. &dwStatus);
  1076. }
  1077. else {
  1078. vpvOut = pti->pThkMgr->FindProxy1632(vpvPreAlloc, punkThis32Out,
  1079. NULL, iidx, &dwStatus);
  1080. }
  1081. if(vpvOut) {
  1082. if((thop & THOP_OPMASK) == THOP_UNKINNER) {
  1083. if (dwStatus != FST_SHORTCUT) {
  1084. THUNK1632OBJ UNALIGNED *pProxy1632;
  1085. // Obtain the holder
  1086. pProxy1632 = FIXVDMPTR(vpvOut, THUNK1632OBJ);
  1087. pph = pProxy1632->pphHolder;
  1088. // Assert invariants in debug builds
  1089. thkAssert(pph->dwFlags & PH_AGGREGATEE);
  1090. thkAssert(dwStatus == FST_CREATED_NEW);
  1091. // Mark the proxy as representing inner unknown
  1092. pProxy1632->grfFlags = PROXYFLAG_PUNKINNER;
  1093. }
  1094. }
  1095. // Either the preallocated proxy was used and freed
  1096. vpvPreAlloc = NULL;
  1097. }
  1098. else {
  1099. pti->scResult = E_OUTOFMEMORY;
  1100. dwResult = (DWORD)E_OUTOFMEMORY;
  1101. }
  1102. // Release the actual 32-bit interface. If a proxy to the
  1103. // 32-bit interface could not be created above, this could
  1104. // be the last release on the 32-bit interface
  1105. punkThis32Out->Release();
  1106. }
  1107. // Set the OUT parameter
  1108. pvpvOut = FIXVDMPTR(vpv, VPVOID);
  1109. *pvpvOut = vpvOut;
  1110. RELVDMPTR(vpv);
  1111. thkDebugOut((DEB_ARGS, "%sOut1632 %s %p -> %p\n",
  1112. NestingLevelString(), IidIdxString(iidx),
  1113. punkThis32Out, vpvOut));
  1114. }
  1115. if(punkThis32In) {
  1116. if((thop & THOP_INOUT) == THOP_INOUT) {
  1117. // IN-OUT parameter.
  1118. thkAssert(vpvIn);
  1119. // Release the 16-bit side interface
  1120. ReleaseOnObj16(vpvIn);
  1121. }
  1122. else {
  1123. // Just an IN parameter
  1124. thkAssert(thop & THOP_IN);
  1125. #if DBG==1
  1126. // Ensure that the following is not the last release
  1127. // on the IN parameter
  1128. THKSTATE thkstate;
  1129. // Remember the current thunk state
  1130. thkstate = pti->pThkMgr->GetThkState();
  1131. // Set the thunk state to THKSTATE_VERIFYINPARAM
  1132. pti->pThkMgr->SetThkState(THKSTATE_VERIFY16INPARAM);
  1133. #endif
  1134. // Release the 32-bit side interface
  1135. punkThis32In->Release();
  1136. #if DBG==1
  1137. // Restore previous thunk state
  1138. pti->pThkMgr->SetThkState(thkstate);
  1139. #endif
  1140. }
  1141. }
  1142. // Cleanup
  1143. if(vpvPreAlloc) {
  1144. // Free preallocated proxy as it was not used
  1145. pti->pThkMgr->FreeNewProxy1632(vpvPreAlloc, iidx);
  1146. }
  1147. if (bUnlinkAggHolder)
  1148. TlsThkUnlinkAggHolder();
  1149. return dwResult;
  1150. }
  1151. //+---------------------------------------------------------------------------
  1152. //
  1153. // Function: Thop_IFACEGEN_1632, public
  1154. //
  1155. // Synopsis: Thunks interfaces out through ppvs from 16->32
  1156. //
  1157. // Arguments: [pti] - Thunk state information
  1158. //
  1159. // Returns: Appropriate status code
  1160. //
  1161. // History: 23-Feb-94 DrewB Created
  1162. //
  1163. //----------------------------------------------------------------------------
  1164. DWORD Thop_IFACEGEN_1632(THUNKINFO *pti)
  1165. {
  1166. IIDIDX iidx;
  1167. THOP thop, thopOp, thopWeakOffset;
  1168. VPVOID vpvIid;
  1169. IUnknown *punkOuter;
  1170. IID UNALIGNED const *piid;
  1171. thop = *pti->pThop++;
  1172. thopOp = thop & THOP_OPMASK;
  1173. thkAssert(thopOp == THOP_IFACEGEN ||
  1174. thopOp == THOP_IFACEGENOWNER);
  1175. // The current thop byte indicates how many bytes to look
  1176. // back in the stack to find the IID which identifies the
  1177. // interface being returned
  1178. INDEX_STACK16(pti, vpvIid, VPVOID, *pti->pThop, sizeof(VPVOID));
  1179. pti->pThop++;
  1180. piid = (IID const *)GetReadPtr16(pti, vpvIid, sizeof(IID const));
  1181. if (piid == NULL)
  1182. {
  1183. pti->scResult = E_INVALIDARG;
  1184. }
  1185. else
  1186. {
  1187. #if DBG == 1
  1188. if (!IsValidIid(*piid))
  1189. {
  1190. pti->scResult = E_INVALIDARG;
  1191. }
  1192. else
  1193. #endif
  1194. {
  1195. iidx = IidToIidIdx(*piid);
  1196. }
  1197. WOWRELVDMPTR(vpvIid);
  1198. }
  1199. if (FAILED(pti->scResult))
  1200. return pti->scResult;
  1201. punkOuter = NULL;
  1202. if (thopOp == THOP_IFACEGENOWNER)
  1203. {
  1204. // Obtain the outer unknown that is being passed to the 32 bit world
  1205. thopWeakOffset = *pti->pThop++;
  1206. INDEX_STACK32(pti, punkOuter, IUnknown *, thopWeakOffset);
  1207. if(punkOuter) {
  1208. // Aggregation across 16-32 boundary
  1209. // Assert that the IID requested is IID_IUnknown
  1210. thkAssert(iidx == THI_IUnknown ||
  1211. (pti->iidx==THI_IPSFactoryBuffer && pti->dwMethod==3));
  1212. // Change thop to indicate that inner unknown is being thunked
  1213. if(iidx == THI_IUnknown)
  1214. thop = (thop & THOP_IOMASK) | THOP_UNKINNER;
  1215. }
  1216. }
  1217. return ThunkInterface1632(pti, iidx, thop, punkOuter);
  1218. }
  1219. //+---------------------------------------------------------------------------
  1220. //
  1221. // Function: Thop_OIFI_1632, public
  1222. //
  1223. // Synopsis: Convert OLEINPLACEFRAMEINFO
  1224. //
  1225. // Arguments: [pti] - Thunking state information
  1226. //
  1227. // Returns: Appropriate status code
  1228. //
  1229. // History: 26-May-94 DrewB Created
  1230. //
  1231. //----------------------------------------------------------------------------
  1232. DWORD Thop_OIFI_1632( THUNKINFO *pti )
  1233. {
  1234. DWORD dwResult;
  1235. VPVOID vpoifi16;
  1236. OIFI16 UNALIGNED *poifi16;
  1237. OLEINPLACEFRAMEINFO oifi32;
  1238. OLEINPLACEFRAMEINFO *poifi32;
  1239. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_OIFI);
  1240. thkAssert((*pti->pThop & THOP_IOMASK) == THOP_OUT);
  1241. // OIFIs are out-only parameters for their contents
  1242. // However, cb is in/out, so we need to copy cb on the way in
  1243. // Furthermore, cb may not be set to a valid value, in which
  1244. // case the documentation mentions that it should be assumed
  1245. // that this is an OLE 2.0 OIFI
  1246. // This thop simply ignores cb on the way in and always sets
  1247. // it to the OLE 2.0 size
  1248. // Since we're out-only, this always works since the number of
  1249. // fields we thunk is the size of the structure that we give out
  1250. // If OLEINPLACEFRAMEINFO is extended, this thop will break
  1251. // Assert that OLEINPLACEFRAMEINFO is what we expect it to be
  1252. thkAssert(sizeof(OLEINPLACEFRAMEINFO) == 20);
  1253. GET_STACK16(pti, vpoifi16, VPVOID);
  1254. poifi32 = NULL;
  1255. if (vpoifi16 != 0)
  1256. {
  1257. poifi16 = (OIFI16 UNALIGNED *) GetWritePtr16(pti, vpoifi16, sizeof(OIFI16));
  1258. if (NULL != poifi16)
  1259. {
  1260. poifi32 = &oifi32;
  1261. // OIFI's may be an out only parameters but if the "cb" field is
  1262. // "in" RPC doesn't slice up structs, so the whole thing is "in"
  1263. // as well. We are Thoping here but if we want this to match
  1264. // the RPC sematics then we need to copy all the fields.
  1265. poifi32 = &oifi32;
  1266. poifi32->cb = sizeof(OLEINPLACEFRAMEINFO);
  1267. poifi32->fMDIApp = (BOOL)poifi16->fMDIApp;
  1268. poifi32->hwndFrame = HWND_32(poifi16->hwndFrame);
  1269. poifi32->cAccelEntries = (UINT)poifi16->cAccelEntries;
  1270. if (poifi16->haccel == NULL)
  1271. {
  1272. poifi32->haccel = NULL;
  1273. }
  1274. else
  1275. {
  1276. // WOW will clean up any dangling accelerator tables when
  1277. // tasks die
  1278. poifi32->haccel = HACCEL_32(poifi16->haccel);
  1279. if (poifi32->haccel == NULL)
  1280. {
  1281. dwResult = (DWORD)E_UNEXPECTED;
  1282. }
  1283. }
  1284. WOWRELVDMPTR(vpoifi16);
  1285. }
  1286. }
  1287. TO_STACK32(pti, poifi32, OLEINPLACEFRAMEINFO *);
  1288. pti->pThop++;
  1289. dwResult = EXECUTE_THOP1632(pti);
  1290. if (poifi32 != NULL)
  1291. {
  1292. poifi16 = FIXVDMPTR(vpoifi16, OIFI16);
  1293. if (SUCCEEDED(dwResult))
  1294. {
  1295. poifi16->cb = sizeof(OIFI16);
  1296. poifi16->fMDIApp = (WORD)poifi32->fMDIApp;
  1297. poifi16->hwndFrame = HWND_16(poifi32->hwndFrame);
  1298. poifi16->cAccelEntries =
  1299. ClampULongToUShort(poifi32->cAccelEntries);
  1300. if (poifi32->haccel == NULL)
  1301. {
  1302. poifi16->haccel = NULL;
  1303. }
  1304. else
  1305. {
  1306. // WOW will clean up any dangling accelerator tables when
  1307. // tasks die
  1308. poifi16->haccel = HACCEL_16(poifi32->haccel);
  1309. if (poifi16->haccel == NULL)
  1310. {
  1311. dwResult = (DWORD)E_UNEXPECTED;
  1312. }
  1313. }
  1314. #if DBG == 1
  1315. if (SUCCEEDED(dwResult))
  1316. {
  1317. thkDebugOut((DEB_ARGS, "Out1632 OIFI: "
  1318. "%p {%d, %d, 0x%p, 0x%p, %d} -> "
  1319. "%p {%d, %d, 0x%04X, 0x%04X, %d}\n",
  1320. poifi32, poifi32->cb, poifi32->fMDIApp,
  1321. poifi32->hwndFrame, poifi32->haccel,
  1322. poifi32->cAccelEntries,
  1323. vpoifi16, poifi16->cb, (BOOL)poifi16->fMDIApp,
  1324. (DWORD)poifi16->hwndFrame, (DWORD)poifi16->haccel,
  1325. poifi16->cAccelEntries));
  1326. }
  1327. #endif
  1328. }
  1329. if (FAILED(dwResult))
  1330. {
  1331. memset(poifi16, 0, sizeof(OIFI16));
  1332. }
  1333. RELVDMPTR(vpoifi16);
  1334. }
  1335. return dwResult;
  1336. }
  1337. //+---------------------------------------------------------------------------
  1338. //
  1339. // Function: Thop_STGMEDIUM_1632, public
  1340. //
  1341. // Synopsis: Converts 32-bit STGMEDIUM to 16-bit STGMEDIUM returned
  1342. // structure
  1343. //
  1344. // Arguments: [pti] - Thunk state information
  1345. //
  1346. // Returns: Appropriate status code
  1347. //
  1348. // History: 23-Feb-94 BobDay Created
  1349. //
  1350. //----------------------------------------------------------------------------
  1351. DWORD Thop_STGMEDIUM_1632( THUNKINFO *pti )
  1352. {
  1353. DWORD dwResult;
  1354. BOOL fThopInput;
  1355. BOOL fThopOutput;
  1356. VPVOID vpstgmedium16;
  1357. STGMEDIUM UNALIGNED *lpstgmedium16;
  1358. STGMEDIUM *lpstgmedium32;
  1359. STGMEDIUM stgmedium32;
  1360. DWORD dwSize;
  1361. SCODE sc;
  1362. BOOL fReleaseParam;
  1363. SHORT fTransferOwnership;
  1364. FORMATETC *pfe;
  1365. THOP thopFeOffset;
  1366. BOOL fReversedTYMED_NULL = FALSE;
  1367. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_STGMEDIUM);
  1368. fThopInput = IS_THOP_IN(pti);
  1369. fThopOutput = IS_THOP_OUT(pti);
  1370. //
  1371. // We currently don't have any unmodified or inout thops for STGMEDIUMs
  1372. //
  1373. thkAssert( (fThopInput || fThopOutput) &&
  1374. (fThopInput != fThopOutput) &&
  1375. "STGMEDIUM must be input or output only" );
  1376. // +2 thop byte indicates whether there's a FORMATETC to look at
  1377. // or not
  1378. // We need to reference this now before the stack is modified
  1379. // by argument recovery
  1380. thopFeOffset = *(pti->pThop+2);
  1381. if (thopFeOffset > 0)
  1382. {
  1383. INDEX_STACK32(pti, pfe, FORMATETC *, thopFeOffset);
  1384. }
  1385. else
  1386. {
  1387. pfe = NULL;
  1388. }
  1389. GET_STACK16(pti, vpstgmedium16, VPVOID);
  1390. // Next thop byte indicates whether there's an ownership transfer
  1391. // argument or not
  1392. pti->pThop++;
  1393. fReleaseParam = (BOOL)*pti->pThop++;
  1394. if (fReleaseParam)
  1395. {
  1396. GET_STACK16(pti, fTransferOwnership, SHORT);
  1397. }
  1398. else
  1399. {
  1400. fTransferOwnership = FALSE;
  1401. }
  1402. // Skip FORMATETC offset thop
  1403. pti->pThop++;
  1404. lpstgmedium32 = NULL;
  1405. if ( vpstgmedium16 != 0 )
  1406. {
  1407. if ( fThopInput )
  1408. {
  1409. // This code supports GetDataHere() passing TYMED_NULL. It then
  1410. // behaves like GetData(). This is not per the OLE spec.
  1411. // According to every OLE spec TYMED_NULL is an invalid type in
  1412. // GetDataHere(). But AlexGo says that 16bit inproc servers
  1413. // did support this, especially the Default Handler / Clipboard.
  1414. lpstgmedium16 = (STGMEDIUM FAR *)GetReadPtr16(pti, vpstgmedium16,
  1415. sizeof(STGMEDIUM));
  1416. thkAssert(lpstgmedium16);
  1417. // To fix a prefix bug... vpstgmedium should never be invalid, but
  1418. // if it is, we'll get back NULL, so we'll return E_UNEXPECTED.
  1419. if (lpstgmedium16)
  1420. {
  1421. if (lpstgmedium16->tymed == TYMED_NULL &&
  1422. !fTransferOwnership)
  1423. {
  1424. WOWRELVDMPTR(vpstgmedium16);
  1425. memset(&stgmedium32, 0, sizeof(stgmedium32));
  1426. thkAssert( TYMED_NULL == 0 ); // Don't need to set tymed to 0
  1427. fThopInput = FALSE;
  1428. fThopOutput = TRUE;
  1429. fReversedTYMED_NULL = TRUE;
  1430. }
  1431. else
  1432. {
  1433. WOWRELVDMPTR(vpstgmedium16);
  1434. sc = ConvertStgMed1632(pti, vpstgmedium16, &stgmedium32,
  1435. pfe, fTransferOwnership, &dwSize);
  1436. if (SUCCEEDED(sc))
  1437. {
  1438. lpstgmedium32 = &stgmedium32;
  1439. }
  1440. }
  1441. }
  1442. else
  1443. {
  1444. return E_UNEXPECTED;
  1445. }
  1446. }
  1447. if ( fThopOutput )
  1448. {
  1449. thkAssert( fThopOutput );
  1450. lpstgmedium16 = (STGMEDIUM FAR *)GetWritePtr16(pti, vpstgmedium16,
  1451. sizeof(STGMEDIUM));
  1452. if ( lpstgmedium16 != NULL )
  1453. {
  1454. lpstgmedium32 = &stgmedium32;
  1455. WOWRELVDMPTR(vpstgmedium16);
  1456. }
  1457. // 32->16 sets tymed to TYMED_NULL before passing
  1458. // on the STGMEDIUM because some apps incorrectly check for this
  1459. // I'm assuming this isn't necessary for 16->32 because 32-bit
  1460. // apps can't rely on tymed being NULL since nothing in the 32-bit
  1461. // code sets it that way for out parameters
  1462. // DrewB 5/30
  1463. }
  1464. }
  1465. TO_STACK32(pti, lpstgmedium32, STGMEDIUM FAR *);
  1466. if (fReleaseParam)
  1467. {
  1468. TO_STACK32(pti, (BOOL)fTransferOwnership, BOOL);
  1469. }
  1470. dwResult = EXECUTE_THOP1632(pti);
  1471. if ( lpstgmedium32 != NULL)
  1472. {
  1473. if ( fThopInput )
  1474. {
  1475. if (!fTransferOwnership || FAILED(dwResult))
  1476. {
  1477. sc = CleanStgMed32(pti, lpstgmedium32, vpstgmedium16,
  1478. dwSize, TRUE, pfe);
  1479. if (FAILED(sc))
  1480. {
  1481. dwResult = (DWORD)sc;
  1482. }
  1483. }
  1484. else if (SUCCEEDED(dwResult))
  1485. {
  1486. lpstgmedium16 = FIXVDMPTR(vpstgmedium16, STGMEDIUM);
  1487. if (lpstgmedium16->pUnkForRelease == NULL)
  1488. {
  1489. RELVDMPTR(vpstgmedium16);
  1490. sc = CleanStgMed16(pti, vpstgmedium16, lpstgmedium32,
  1491. 0, FALSE, pfe);
  1492. thkAssert(SUCCEEDED(sc));
  1493. }
  1494. else
  1495. {
  1496. RELVDMPTR(vpstgmedium16);
  1497. }
  1498. }
  1499. }
  1500. else
  1501. {
  1502. thkAssert( fThopOutput );
  1503. if (SUCCEEDED(dwResult))
  1504. {
  1505. sc = ConvertStgMed3216(pti, lpstgmedium32, vpstgmedium16,
  1506. pfe, FALSE, &dwSize);
  1507. if (FAILED(sc))
  1508. {
  1509. dwResult = (DWORD)sc;
  1510. ReleaseStgMedium(lpstgmedium32);
  1511. }
  1512. else if (lpstgmedium32->pUnkForRelease == NULL)
  1513. {
  1514. sc = CleanStgMed32(pti, lpstgmedium32, vpstgmedium16,
  1515. dwSize, FALSE, pfe);
  1516. thkAssert(SUCCEEDED(sc));
  1517. }
  1518. }
  1519. // Clear the [out] parameters if the call failed.
  1520. // Unless it had previously been an [in] parameter.
  1521. // We don't want to erase the caller's [in] argument.
  1522. if (FAILED(dwResult) && !fReversedTYMED_NULL)
  1523. {
  1524. lpstgmedium16 = FIXVDMPTR(vpstgmedium16, STGMEDIUM);
  1525. memset(lpstgmedium16, 0, sizeof(STGMEDIUM));
  1526. RELVDMPTR(vpstgmedium16);
  1527. }
  1528. }
  1529. }
  1530. return dwResult;
  1531. }
  1532. //+---------------------------------------------------------------------------
  1533. //
  1534. // Function: ConvertStatStg3216, public
  1535. //
  1536. // Synopsis: Converts a STATSTG
  1537. //
  1538. // Arguments: [pti] - Thunk info
  1539. // [pss32] - STATSTG
  1540. // [vpss16] - STATSTG
  1541. // [vpstrPreAlloc] - Preallocated string memory or NULL
  1542. // [cchPreAlloc] - Amount preallocated
  1543. //
  1544. // Returns: Appropriate status code
  1545. //
  1546. // Modifies: [vpss16]
  1547. //
  1548. // History: 14-May-94 DrewB Created
  1549. //
  1550. // Notes: Assumes input STATSTG memory is valid
  1551. // Assumes task memory for the string
  1552. //
  1553. //----------------------------------------------------------------------------
  1554. SCODE ConvertStatStg3216(THUNKINFO *pti,
  1555. STATSTG *pss32,
  1556. VPVOID vpss16,
  1557. VPSTR vpstrPreAlloc,
  1558. UINT cchPreAlloc)
  1559. {
  1560. STATSTG UNALIGNED *pss16;
  1561. SCODE sc;
  1562. VPSTR vpstr16;
  1563. sc = ConvertTaskString3216(pti, pss32->pwcsName,
  1564. vpstrPreAlloc, cchPreAlloc,
  1565. &vpstr16);
  1566. if (SUCCEEDED(sc))
  1567. {
  1568. pss16 = FIXVDMPTR(vpss16, STATSTG);
  1569. memcpy(pss16, pss32, sizeof(STATSTG));
  1570. pss16->pwcsName = (LPOLESTR)vpstr16;
  1571. RELVDMPTR(vpss16);
  1572. }
  1573. return sc;
  1574. }
  1575. //+---------------------------------------------------------------------------
  1576. //
  1577. // Function: Thop_STATSTG_1632, public
  1578. //
  1579. // Synopsis: Converts 32-bit STATSTG to 16-bit STATSTG returned structure
  1580. //
  1581. // Arguments: [pti] - Thunk state information
  1582. //
  1583. // Returns: Appropriate status code
  1584. //
  1585. // History: 23-Feb-94 BobDay Created
  1586. //
  1587. //----------------------------------------------------------------------------
  1588. DWORD Thop_STATSTG_1632( THUNKINFO *pti )
  1589. {
  1590. DWORD dwResult;
  1591. VPVOID vpstatstg16;
  1592. STATSTG UNALIGNED *lpstatstg16;
  1593. VPSTR vpstr;
  1594. STATSTG statstg32;
  1595. STATSTG *lpstatstg32;
  1596. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_STATSTG);
  1597. //
  1598. // We currently don't have any input thops for STATSTGs
  1599. //
  1600. thkAssert( (*pti->pThop & THOP_IOMASK) == THOP_OUT &&
  1601. "STATSTG must be output only" );
  1602. GET_STACK16(pti, vpstatstg16, VPVOID);
  1603. lpstatstg32 = NULL;
  1604. lpstatstg16 = (STATSTG FAR *)GetWritePtr16( pti, vpstatstg16,
  1605. sizeof(STATSTG) );
  1606. if ( lpstatstg16 != NULL )
  1607. {
  1608. statstg32.pwcsName = NULL;
  1609. lpstatstg32 = &statstg32;
  1610. vpstr = (VPSTR)TaskMalloc16(CBSTRINGPREALLOC);
  1611. if (vpstr == 0)
  1612. {
  1613. pti->scResult = E_OUTOFMEMORY;
  1614. }
  1615. WOWRELVDMPTR(vpstatstg16);
  1616. }
  1617. TO_STACK32(pti, lpstatstg32, STATSTG FAR *);
  1618. pti->pThop++;
  1619. dwResult = EXECUTE_THOP1632(pti);
  1620. if ( lpstatstg32 != NULL )
  1621. {
  1622. if ( SUCCEEDED(dwResult) )
  1623. {
  1624. SCODE sc;
  1625. sc = ConvertStatStg3216(pti, &statstg32, vpstatstg16,
  1626. vpstr, CWCSTRINGPREALLOC);
  1627. if (FAILED(sc))
  1628. {
  1629. dwResult = sc;
  1630. }
  1631. }
  1632. if (FAILED(dwResult))
  1633. {
  1634. TaskFree16(vpstr);
  1635. lpstatstg16 = FIXVDMPTR(vpstatstg16, STATSTG);
  1636. memset(lpstatstg16, 0, sizeof(STATSTG));
  1637. RELVDMPTR(vpstatstg16);
  1638. }
  1639. }
  1640. return dwResult;
  1641. }
  1642. //+---------------------------------------------------------------------------
  1643. //
  1644. // Function: Thop_DVTARGETDEVICE_1632, public
  1645. //
  1646. // Synopsis: Converts 16-bit DVTARGETDEVICE to 32-bit DVTARGETDEVICE
  1647. //
  1648. // Arguments: [pti] - Thunk state information
  1649. //
  1650. // Returns: Appropriate status code
  1651. //
  1652. // History: 23-Feb-94 BobDay Created
  1653. //
  1654. //----------------------------------------------------------------------------
  1655. DWORD Thop_DVTARGETDEVICE_1632( THUNKINFO *pti )
  1656. {
  1657. DWORD dwResult;
  1658. UINT uiSize;
  1659. DVTARGETDEVICE *lpdv32;
  1660. VPVOID vpdv16;
  1661. SCODE sc;
  1662. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_DVTARGETDEVICE);
  1663. //
  1664. // We currently don't have any output thops for DVTARGETDEVICEs
  1665. //
  1666. thkAssert( (*pti->pThop & THOP_IOMASK) == THOP_IN &&
  1667. "DVTARGETDEVICE must be input only" );
  1668. //
  1669. // Processing for a DVTARGETDEVICE FAR * as input
  1670. //
  1671. GET_STACK16(pti, vpdv16, VPVOID);
  1672. lpdv32 = NULL;
  1673. if ( vpdv16 != 0 )
  1674. {
  1675. sc = ConvertDvtd1632(pti, vpdv16, ArStack32, FrStack32, &lpdv32,
  1676. &uiSize);
  1677. if (FAILED(sc))
  1678. {
  1679. pti->scResult = sc;
  1680. }
  1681. }
  1682. TO_STACK32(pti, lpdv32, DVTARGETDEVICE FAR *);
  1683. pti->pThop++;
  1684. dwResult = EXECUTE_THOP1632(pti);
  1685. if (lpdv32 != NULL)
  1686. {
  1687. FrStack32(lpdv32, uiSize);
  1688. }
  1689. return dwResult;
  1690. }
  1691. //+---------------------------------------------------------------------------
  1692. //
  1693. // Function: Thop_FORMATETC_1632, public
  1694. //
  1695. // Synopsis: Converts 16-bit FORMATETC to 32-bit FORMATETC and back
  1696. //
  1697. // Arguments: [pti] - Thunk state information
  1698. //
  1699. // Returns: Appropriate status code
  1700. //
  1701. // History: 24-Feb-94 BobDay Created
  1702. //
  1703. //----------------------------------------------------------------------------
  1704. DWORD Thop_FORMATETC_1632( THUNKINFO *pti )
  1705. {
  1706. DWORD dwResult;
  1707. BOOL fThopInput;
  1708. BOOL fThopOutput;
  1709. VPVOID vpformatetc16;
  1710. FORMATETC16 UNALIGNED *lpformatetc16;
  1711. LPFORMATETC lpformatetc32;
  1712. FORMATETC formatetc32;
  1713. DVTARGETDEVICE *lpdv32;
  1714. SCODE sc;
  1715. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_FORMATETC);
  1716. fThopInput = IS_THOP_IN(pti);
  1717. fThopOutput = IS_THOP_OUT(pti);
  1718. //
  1719. // We have only input and output thops, not both, or neither
  1720. //
  1721. thkAssert( (fThopInput || fThopOutput) &&
  1722. (fThopInput != fThopOutput) &&
  1723. "formatetc must be input or output only" );
  1724. lpdv32 = NULL;
  1725. GET_STACK16(pti, vpformatetc16, VPVOID);
  1726. if ( vpformatetc16 == 0 )
  1727. {
  1728. lpformatetc32 = NULL;
  1729. }
  1730. else
  1731. {
  1732. lpformatetc32 = &formatetc32;
  1733. if ( fThopInput )
  1734. {
  1735. sc = ConvertFetc1632(pti, vpformatetc16, lpformatetc32, FALSE);
  1736. if (FAILED(sc))
  1737. {
  1738. pti->scResult = sc;
  1739. }
  1740. }
  1741. else
  1742. {
  1743. thkAssert( fThopOutput );
  1744. //
  1745. // The below memset is needed at least for the DATA_S_SAMEFORMATETC
  1746. // case. This allows it to be cleaned up because all its pointers
  1747. // will be null.
  1748. //
  1749. memset( &formatetc32, 0, sizeof(formatetc32) );
  1750. lpformatetc16 = (LPFORMATETC16)GetWritePtr16(pti, vpformatetc16,
  1751. sizeof(FORMATETC16));
  1752. WOWRELVDMPTR(vpformatetc16);
  1753. }
  1754. }
  1755. TO_STACK32(pti, lpformatetc32, LPFORMATETC);
  1756. pti->pThop++;
  1757. dwResult = EXECUTE_THOP1632(pti);
  1758. if ( fThopInput )
  1759. {
  1760. if (lpformatetc32 != NULL && lpformatetc32->ptd != NULL)
  1761. {
  1762. TaskFree32(lpformatetc32->ptd);
  1763. }
  1764. }
  1765. if ( fThopOutput && vpformatetc16 != NULL)
  1766. {
  1767. if (SUCCEEDED(dwResult))
  1768. {
  1769. sc = ConvertFetc3216(pti, lpformatetc32, vpformatetc16, TRUE);
  1770. if (FAILED(sc))
  1771. {
  1772. dwResult = sc;
  1773. }
  1774. }
  1775. if (FAILED(dwResult))
  1776. {
  1777. lpformatetc16 = FIXVDMPTR(vpformatetc16, FORMATETC16);
  1778. memset(lpformatetc16, 0, sizeof(FORMATETC16));
  1779. RELVDMPTR(vpformatetc16);
  1780. }
  1781. }
  1782. return dwResult;
  1783. }
  1784. //+---------------------------------------------------------------------------
  1785. //
  1786. // Function: Thop_LOGPALETTE_1632, public
  1787. //
  1788. // Synopsis: Converts 16-bit LOGPALLETE to 32-bit LOGPALETTE
  1789. // and converts 32-bit LOGPALETTE returned to 16-bit structure
  1790. //
  1791. // Arguments: [pti] - Thunk state information
  1792. //
  1793. // Returns: Appropriate status code
  1794. //
  1795. // History: 23-Feb-94 BobDay Created
  1796. //
  1797. //----------------------------------------------------------------------------
  1798. DWORD Thop_LOGPALETTE_1632 ( THUNKINFO *pti )
  1799. {
  1800. DWORD dwResult;
  1801. UINT uiSize;
  1802. LPLOGPALETTE lplogpal32;
  1803. VPVOID vplogpal16;
  1804. LOGPALETTE UNALIGNED *lplogpal16;
  1805. VPVOID vp16;
  1806. LPVOID UNALIGNED *lp16;
  1807. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_LOGPALETTE);
  1808. //
  1809. // It must be either an input or output LOGPALETTE
  1810. //
  1811. thkAssert( ((*pti->pThop & THOP_IOMASK) == THOP_IN ||
  1812. (*pti->pThop & THOP_IOMASK) == THOP_OUT) &&
  1813. "Hey, LOGPALETTE can't be input and output!" );
  1814. lplogpal32 = NULL;
  1815. if ( (*pti->pThop & THOP_IN) != 0 )
  1816. {
  1817. //
  1818. // Processing for a LPLOGPALETTE as input
  1819. //
  1820. GET_STACK16(pti, vplogpal16, VPVOID);
  1821. if ( vplogpal16 != 0 )
  1822. {
  1823. // Copy over the input LOGPALETTE structure
  1824. lplogpal16 = (LPLOGPALETTE)GetReadPtr16( pti, vplogpal16,
  1825. sizeof(LOGPALETTE) );
  1826. if ( lplogpal16 != NULL )
  1827. {
  1828. uiSize = CBPALETTE(lplogpal16->palNumEntries);
  1829. WOWRELVDMPTR(vplogpal16);
  1830. lplogpal16 = (LPLOGPALETTE)GetReadPtr16(pti, vplogpal16,
  1831. uiSize);
  1832. if ( lplogpal16 != NULL )
  1833. {
  1834. lplogpal32 = (LPLOGPALETTE)CoTaskMemAlloc(uiSize);
  1835. if ( lplogpal32 == NULL )
  1836. {
  1837. pti->scResult = E_OUTOFMEMORY;
  1838. }
  1839. else
  1840. {
  1841. memcpy( lplogpal32, lplogpal16, uiSize );
  1842. }
  1843. WOWRELVDMPTR(vplogpal16);
  1844. }
  1845. }
  1846. }
  1847. TO_STACK32(pti, lplogpal32, LPLOGPALETTE);
  1848. pti->pThop++;
  1849. dwResult = EXECUTE_THOP1632(pti);
  1850. if ( lplogpal32 )
  1851. {
  1852. CoTaskMemFree( lplogpal32 );
  1853. }
  1854. }
  1855. else
  1856. {
  1857. //
  1858. // Processing for LPLPLOGPALETTE as output
  1859. //
  1860. thkAssert((*pti->pThop & THOP_OUT) != 0);
  1861. GET_STACK16(pti, vp16, VPVOID);
  1862. vplogpal16 = (VPVOID)TaskMalloc16(CBPALETTE(NPALETTEPREALLOC));
  1863. if (vplogpal16 == 0)
  1864. {
  1865. pti->scResult = E_OUTOFMEMORY;
  1866. }
  1867. TO_STACK32(pti, &lplogpal32, LPLOGPALETTE *);
  1868. pti->pThop++;
  1869. dwResult = EXECUTE_THOP1632(pti);
  1870. if ( SUCCEEDED(dwResult) && lplogpal32 != NULL )
  1871. {
  1872. //
  1873. // Copy the returned LOGPALETTE into 16-bit memory
  1874. //
  1875. uiSize = CBPALETTE(lplogpal32->palNumEntries);
  1876. if (uiSize > CBPALETTE(NPALETTEPREALLOC))
  1877. {
  1878. TaskFree16(vplogpal16);
  1879. vplogpal16 = (VPVOID)TaskMalloc16(uiSize);
  1880. if ( vplogpal16 == 0 )
  1881. {
  1882. dwResult = (DWORD)E_OUTOFMEMORY;
  1883. }
  1884. }
  1885. if (vplogpal16 != 0)
  1886. {
  1887. lplogpal16 = (LPLOGPALETTE)WOWFIXVDMPTR(vplogpal16, uiSize);
  1888. if ( lplogpal16 == NULL )
  1889. {
  1890. dwResult = (DWORD)E_UNEXPECTED;
  1891. vplogpal16 = 0;
  1892. }
  1893. else
  1894. {
  1895. memcpy( lplogpal16, lplogpal32, uiSize );
  1896. WOWRELVDMPTR(vplogpal16);
  1897. }
  1898. }
  1899. TaskFree32( lplogpal32 );
  1900. }
  1901. else
  1902. {
  1903. TaskFree16(vplogpal16);
  1904. vplogpal16 = 0;
  1905. }
  1906. //
  1907. // Update the value pointed to by the parameter on the 16-bit stack
  1908. //
  1909. lp16 = FIXVDMPTR(vp16, LPVOID);
  1910. if ( lp16 == NULL )
  1911. {
  1912. dwResult = (DWORD)E_UNEXPECTED;
  1913. }
  1914. else
  1915. {
  1916. *lp16 = (LPVOID)vplogpal16;
  1917. RELVDMPTR(vp16);
  1918. }
  1919. }
  1920. return dwResult;
  1921. }
  1922. //+---------------------------------------------------------------------------
  1923. //
  1924. // Function: Thop_CRGIID_1632, public
  1925. //
  1926. // Synopsis: Converts 16-bit CRGIID to 32-bit CRGIID structure
  1927. //
  1928. // Arguments: [pti] - Thunk state information
  1929. //
  1930. // Returns: Appropriate status code
  1931. //
  1932. // History: 23-Feb-94 BobDay Created
  1933. //
  1934. //----------------------------------------------------------------------------
  1935. DWORD Thop_CRGIID_1632( THUNKINFO *pti )
  1936. {
  1937. DWORD dwResult;
  1938. DWORD dwCount;
  1939. VPVOID vpiid16;
  1940. IID UNALIGNED *lpiid16;
  1941. IID *lpiid32;
  1942. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_CRGIID);
  1943. //
  1944. // We currently don't have any output thops for CRGIIDs
  1945. //
  1946. thkAssert( (*pti->pThop & THOP_IOMASK) == 0 &&
  1947. "CRGIID must be unmodified only" );
  1948. GET_STACK16(pti, dwCount, DWORD);
  1949. GET_STACK16(pti, vpiid16, VPVOID);
  1950. lpiid32 = NULL;
  1951. if ( vpiid16 != 0 )
  1952. {
  1953. lpiid16 = (IID UNALIGNED *)GetReadPtr16( pti, vpiid16,
  1954. dwCount*sizeof(IID) );
  1955. if ( lpiid16 != NULL )
  1956. {
  1957. lpiid32 = (IID FAR *)CoTaskMemAlloc( dwCount * sizeof(IID) );
  1958. if ( lpiid32 == NULL )
  1959. {
  1960. pti->scResult = E_OUTOFMEMORY;
  1961. }
  1962. else
  1963. {
  1964. memcpy( lpiid32, lpiid16, dwCount*sizeof(IID) );
  1965. }
  1966. WOWRELVDMPTR(vpiid16);
  1967. }
  1968. }
  1969. TO_STACK32(pti, dwCount, DWORD);
  1970. TO_STACK32(pti, lpiid32, IID FAR *);
  1971. pti->pThop++;
  1972. dwResult = EXECUTE_THOP1632(pti);
  1973. if ( lpiid32 != NULL )
  1974. {
  1975. CoTaskMemFree( lpiid32 );
  1976. }
  1977. return( dwResult );
  1978. }
  1979. //+---------------------------------------------------------------------------
  1980. //
  1981. // Function: Thop_INTERFACEINFO_1632, public
  1982. //
  1983. // Synopsis: Converts an INTERFACEINFO
  1984. //
  1985. // Arguments: [pti] - Thunking state information
  1986. //
  1987. // Returns: Appropriate status code
  1988. //
  1989. // History: 19-May-94 DrewB Created
  1990. //
  1991. //----------------------------------------------------------------------------
  1992. DWORD Thop_INTERFACEINFO_1632(THUNKINFO *pti)
  1993. {
  1994. INTERFACEINFO *pii32;
  1995. INTERFACEINFO ii32;
  1996. INTERFACEINFO16 UNALIGNED *pii16;
  1997. VPVOID vpii16;
  1998. DWORD dwResult;
  1999. IUnknown *punk32;
  2000. VPVOID vpvUnk16;
  2001. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_INTERFACEINFO);
  2002. thkAssert((*pti->pThop & THOP_INOUT) == THOP_IN);
  2003. pii32 = NULL;
  2004. punk32 = NULL;
  2005. GET_STACK16(pti, vpii16, VPVOID);
  2006. if (vpii16 != 0)
  2007. {
  2008. pii16 = (INTERFACEINFO16 UNALIGNED *)
  2009. GetReadPtr16(pti, vpii16, sizeof(INTERFACEINFO16));
  2010. if (pii16 != NULL)
  2011. {
  2012. if (pii16->pUnk != NULL)
  2013. {
  2014. vpvUnk16 = pii16->pUnk;
  2015. WOWRELVDMPTR(vpii16);
  2016. punk32 =
  2017. pti->pThkMgr->FindProxy3216(NULL, vpvUnk16, NULL,
  2018. INDEX_IIDIDX(THI_IUnknown),
  2019. FALSE, NULL);
  2020. if (punk32 == NULL)
  2021. {
  2022. pti->scResult = E_OUTOFMEMORY;
  2023. }
  2024. pii16 = FIXVDMPTR(vpii16, INTERFACEINFO16);
  2025. }
  2026. pii32 = &ii32;
  2027. pii32->pUnk = punk32;
  2028. pii32->iid = pii16->iid;
  2029. pii32->wMethod = pii16->wMethod;
  2030. WOWRELVDMPTR(vpii16);
  2031. thkDebugOut((DEB_ARGS,
  2032. "In1632 INTERFACEINFO: %p -> %p {%p (%p), %s, %u}\n",
  2033. vpii16, pii32, pii32->pUnk, pii16->pUnk,
  2034. IidOrInterfaceString(&pii32->iid), pii32->wMethod));
  2035. }
  2036. }
  2037. TO_STACK32(pti, pii32, INTERFACEINFO *);
  2038. pti->pThop++;
  2039. dwResult = EXECUTE_THOP1632(pti);
  2040. if(punk32) {
  2041. // Release the 32-bit interface as it is an IN parameter
  2042. punk32->Release();
  2043. }
  2044. return dwResult;
  2045. }
  2046. //+---------------------------------------------------------------------------
  2047. //
  2048. // Function: Thop_RETURNTYPE_1632, public
  2049. //
  2050. // Synopsis: Thunks the return value of a call
  2051. //
  2052. // Arguments: [pti] - Thunk state information
  2053. //
  2054. // Returns: Appropriate status code
  2055. //
  2056. // History: 24-Feb-94 DrewB Created
  2057. //
  2058. // Notes: This thunk assumes that the return value will always fit
  2059. // in 32 bits and that the thops for it are only one thop
  2060. // long. This fits the existing APIs and methods
  2061. //
  2062. //----------------------------------------------------------------------------
  2063. DWORD Thop_RETURNTYPE_1632(THUNKINFO *pti)
  2064. {
  2065. THOP thops[2];
  2066. DWORD dwResult;
  2067. ALIAS alias;
  2068. VPVOID vpvPreAlloc = NULL;
  2069. IIDIDX iidx;
  2070. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_RETURNTYPE);
  2071. thkAssert((*pti->pThop & THOP_IOMASK) == 0);
  2072. pti->fResultThunked = TRUE;
  2073. pti->pThop++;
  2074. // Remember return type thop
  2075. thops[0] = *pti->pThop++;
  2076. if ((thops[0] & THOP_OPMASK) == THOP_COPY ||
  2077. (thops[0] & THOP_OPMASK) == THOP_IFACE ||
  2078. (thops[0] & THOP_OPMASK) == THOP_ALIAS32)
  2079. {
  2080. thops[1] = *pti->pThop++;
  2081. }
  2082. // Preallocate any necessary resources
  2083. switch(thops[0])
  2084. {
  2085. case THOP_IFACE | THOP_IN:
  2086. iidx = INDEX_IIDIDX(thops[1]);
  2087. if ((vpvPreAlloc =
  2088. pti->pThkMgr->CanGetNewProxy1632(iidx)) == NULL)
  2089. {
  2090. pti->scResult = E_OUTOFMEMORY;
  2091. }
  2092. break;
  2093. case THOP_ALIAS32:
  2094. thkAssert(thops[1] == ALIAS_CREATE);
  2095. // The value used for preallocation doesn't really matter
  2096. // as long as it's unique and not INVALID_VALUE
  2097. // In our case we know that we won't have to deal with nested
  2098. // preallocations so uniqueness is not as much of an issue
  2099. // By using INVALID_HANDLE_VALUE, we can be sure that there
  2100. // won't already be an entry with that value already in the
  2101. // alias table since we're aliasing handles
  2102. alias = gAliases32.AddValue((DWORD)INVALID_HANDLE_VALUE);
  2103. if (alias == INVALID_ALIAS)
  2104. {
  2105. pti->scResult = E_OUTOFMEMORY;
  2106. }
  2107. break;
  2108. }
  2109. dwResult = EXECUTE_THOP1632(pti);
  2110. // Now that we have the return value thunk it from 32->16
  2111. // We must use pti->scResult to check for failure rather than
  2112. // dwResult because dwResult may not be an SCODE
  2113. switch(thops[0])
  2114. {
  2115. case THOP_COPY:
  2116. // Only handle DWORD copies
  2117. thkAssert(thops[1] == sizeof(DWORD));
  2118. break;
  2119. case THOP_SHORTLONG:
  2120. // For boolean results, not necessary to clamp
  2121. dwResult = (DWORD)(SHORT)*(LONG *)&dwResult;
  2122. break;
  2123. case THOP_IFACE | THOP_IN:
  2124. // Thunking an interface as a return value is completly broken
  2125. // First, such an interface needs to be thunked as an OUT parameter
  2126. // which I am fixing below. Second, the IID of the interface being
  2127. // thunked needs to be in the THOP string for proper thunking of
  2128. // interface. The only known case where an interface is returned
  2129. // is IRpcStubBuffer::IsIIDSupported() and the interface returned
  2130. // is of type IRpcStubBuffer, not IUnknown. As this method is not
  2131. // used in the curremt COM code, I am not changing THOP strings
  2132. // to reflect the IID of the interface being thunked
  2133. // Gopalk Mar 27, 97
  2134. if (dwResult != 0)
  2135. {
  2136. if (FAILED(pti->scResult))
  2137. {
  2138. dwResult = 0;
  2139. }
  2140. else
  2141. {
  2142. IUnknown *punk = (IUnknown *) dwResult;
  2143. dwResult =
  2144. (DWORD)pti->pThkMgr->FindProxy1632(vpvPreAlloc,
  2145. (IUnknown *)dwResult, NULL,
  2146. iidx, NULL);
  2147. // Release actual interface as it is an OUT parameter
  2148. // This could be the last release on the interface if the
  2149. // above call failed;
  2150. punk->Release();
  2151. thkAssert(dwResult);
  2152. thkDebugOut((DEB_ARGS, "Ret1632 %s %p\n",
  2153. inInterfaceNames[thops[1]].pszInterface,
  2154. dwResult));
  2155. }
  2156. }
  2157. else
  2158. {
  2159. pti->pThkMgr->FreeNewProxy1632(vpvPreAlloc, iidx);
  2160. }
  2161. break;
  2162. case THOP_ALIAS32:
  2163. if (dwResult != 0)
  2164. {
  2165. if (FAILED(pti->scResult))
  2166. {
  2167. dwResult = 0;
  2168. }
  2169. else
  2170. {
  2171. gAliases32.SetValue(alias, dwResult);
  2172. thkDebugOut((DEB_ARGS, "Ret1632 ALIAS32: 0x%08lX -> 0x%04lX\n",
  2173. dwResult, alias));
  2174. dwResult = (DWORD)alias;
  2175. }
  2176. }
  2177. break;
  2178. default:
  2179. thkAssert(!"Unhandled 1632 return type");
  2180. break;
  2181. }
  2182. return dwResult;
  2183. }
  2184. //+---------------------------------------------------------------------------
  2185. //
  2186. // Function: Thop_IFACE_1632, public
  2187. //
  2188. // Synopsis: Thunks a known interface pointer
  2189. //
  2190. // Arguments: [pti] - Thunk state information
  2191. //
  2192. // Returns: Appropriate status code
  2193. //
  2194. // History: 24-Feb-94 DrewB Created
  2195. //
  2196. //----------------------------------------------------------------------------
  2197. DWORD Thop_IFACE_1632(THUNKINFO *pti)
  2198. {
  2199. IIDIDX iidx;
  2200. THOP thop, thopOp, thopWeakOffset;
  2201. IUnknown *punkOuter;
  2202. thop = *pti->pThop++;
  2203. thopOp = thop & THOP_OPMASK;
  2204. thkAssert( thopOp == THOP_IFACE
  2205. || thopOp == THOP_IFACEOWNER
  2206. || thopOp == THOP_IFACENOADDREF
  2207. || thopOp == THOP_UNKOUTER);
  2208. iidx = INDEX_IIDIDX(*pti->pThop++);
  2209. // There's a bit of a special case here in that IMalloc is
  2210. // not thunked so it doesn't have a real index but it's used
  2211. // in thop strings so it has a fake index to function as a placeholder
  2212. // The fake index is THI_COUNT so allow that in the assert
  2213. thkAssert(IIDIDX_INDEX(iidx) >= 0 && IIDIDX_INDEX(iidx) <= THI_COUNT);
  2214. thkAssert(thopOp != THOP_UNKOUTER || iidx == THI_IUnknown);
  2215. punkOuter = NULL;
  2216. if ( thopOp == THOP_IFACEOWNER
  2217. || thopOp == THOP_IFACENOADDREF)
  2218. {
  2219. thopWeakOffset = *pti->pThop++;
  2220. INDEX_STACK32(pti, punkOuter, IUnknown *, thopWeakOffset);
  2221. if(punkOuter && (thopOp==THOP_IFACEOWNER)) {
  2222. // Aggregation across 16-32 boundary
  2223. // Assert invariants
  2224. thkAssert(iidx == THI_IRpcProxyBuffer || iidx == THI_IRpcProxy);
  2225. // Change thop to indicate that inner unknown is being thunked
  2226. thop = (thop & THOP_IOMASK) | THOP_UNKINNER;
  2227. }
  2228. }
  2229. return ThunkInterface1632(pti, iidx, thop, punkOuter);
  2230. }
  2231. typedef struct tagOLESTREAMOBJECT
  2232. {
  2233. OLESTREAM os;
  2234. VPVOID vpolestream16;
  2235. } OLESTREAMOBJECT, FAR * LPOLESTREAMOBJECT;
  2236. #define OLESTREAM_GET 0
  2237. #define OLESTREAM_PUT 1
  2238. //+---------------------------------------------------------------------------
  2239. //
  2240. // Function: OLESTREAM_Callback, private
  2241. //
  2242. // Synopsis: Handles callbacks into 16-bit world for OLESTREAM methods
  2243. //
  2244. // Arguments: [dwMethod] - Index of method to invoke
  2245. // [lposo] - Pointer to 32 LPOLESTREAM
  2246. // [lpv] - Pointer to 32 bit buffer
  2247. // [dwCount] - Size of 32 bit buffer
  2248. //
  2249. //
  2250. // Returns: Appropriate status code
  2251. //
  2252. // History: 11-Mar-94 BobDay Created
  2253. // 29-May-94 TerryRu Converted to call WOWCallBackEx directly.
  2254. //
  2255. //----------------------------------------------------------------------------
  2256. DWORD OLESTREAM_Callback( DWORD dwMethod,
  2257. LPOLESTREAM lpos,
  2258. LPVOID lpv,
  2259. DWORD dwCount )
  2260. {
  2261. const DWORD cbStack = sizeof( DWORD ) +
  2262. sizeof( VPVOID ) + sizeof( VPVOID );
  2263. BYTE b32Args[cbStack];
  2264. DWORD dwResult;
  2265. VPVOID vpvVtbl16;
  2266. VTBLFN vpfn16;
  2267. VPVOID vpolestream16;
  2268. LPOLESTREAMOBJECT lposo;
  2269. VPVOID vp16;
  2270. LPVOID lp16;
  2271. lposo = (LPOLESTREAMOBJECT)lpos;
  2272. vpolestream16 = lposo->vpolestream16;
  2273. // Get pointer to 16 bit this pointer
  2274. vpvVtbl16 = (VPVOID)*FIXVDMPTR( vpolestream16, VPVOID );
  2275. RELVDMPTR(vpolestream16);
  2276. vpfn16 = (VTBLFN)*FIXVDMPTR( vpvVtbl16+dwMethod*sizeof(VPVOID),
  2277. VPVOID );
  2278. RELVDMPTR(vpvVtbl16+dwMethod*sizeof(VPVOID));
  2279. //
  2280. // now thop the IN 32 bit-block of memory to 16 bit block
  2281. //
  2282. vp16 = WgtAllocLock( GMEM_MOVEABLE, dwCount, NULL );
  2283. if ( vp16 == NULL )
  2284. {
  2285. return (DWORD) E_OUTOFMEMORY;
  2286. }
  2287. if ( dwMethod == OLESTREAM_PUT )
  2288. {
  2289. lp16 = WOWFIXVDMPTR( vp16, dwCount );
  2290. memcpy( lp16, lpv, dwCount );
  2291. WOWRELVDMPTR(vp16);
  2292. }
  2293. // setup 32 bit arguements.
  2294. *(DWORD *)(b32Args) = dwCount;
  2295. *(VPVOID *)(b32Args+4) = vp16;
  2296. *(VPVOID *)(b32Args+8) = vpolestream16;
  2297. if ( !CallbackTo16Ex( (DWORD)vpfn16, WCB16_PASCAL, cbStack, b32Args,
  2298. &dwResult) )
  2299. {
  2300. dwResult = (DWORD)E_UNEXPECTED;
  2301. }
  2302. if ( dwMethod == OLESTREAM_GET )
  2303. {
  2304. lp16 = WOWFIXVDMPTR( vp16, dwCount );
  2305. memcpy( (LPVOID) lpv, lp16, dwCount );
  2306. WOWRELVDMPTR(vp16);
  2307. }
  2308. WgtUnlockFree(vp16);
  2309. thkDebugOut((DEB_INVOKES, "OLESTREAM_Callback returns 0x%08lX\n",
  2310. dwResult));
  2311. return dwResult;
  2312. }
  2313. //+---------------------------------------------------------------------------
  2314. //
  2315. // Function: OLESTREAM_Get_Proxy, private
  2316. //
  2317. // Synopsis: Handles callbacks into 16-bit world for OLESTREAM::Get
  2318. //
  2319. // Arguments: [pti] - Thunk state information
  2320. //
  2321. // Returns: Appropriate status code
  2322. //
  2323. // History: 11-Mar-94 BobDay Created
  2324. // 29-May-94 TerryRu Now calls OLESTREAM::Get using Pascal
  2325. // calling conventions.
  2326. //
  2327. //----------------------------------------------------------------------------
  2328. DWORD OLESTREAM_Get_Proxy(
  2329. LPOLESTREAM lpos,
  2330. void FAR * lpv,
  2331. DWORD dwCount
  2332. )
  2333. {
  2334. return OLESTREAM_Callback( OLESTREAM_GET, lpos, lpv, dwCount );
  2335. }
  2336. //+---------------------------------------------------------------------------
  2337. //
  2338. // Function: OLESTREAM_Put_Proxy, private
  2339. //
  2340. // Synopsis: Handles callbacks into 16-bit world for OLESTREAM::Put
  2341. //
  2342. // Arguments: [pti] - Thunk state information
  2343. //
  2344. // Returns: Appropriate status code
  2345. //
  2346. // History: 11-Mar-94 BobDay Created
  2347. // 29-May-94 TerryRu Now call OLESTREAM::Put using pascal
  2348. // calling conventions.
  2349. //
  2350. //----------------------------------------------------------------------------
  2351. DWORD OLESTREAM_Put_Proxy(
  2352. LPOLESTREAM lpos,
  2353. const void FAR* lpv,
  2354. DWORD dwCount
  2355. )
  2356. {
  2357. return OLESTREAM_Callback( OLESTREAM_PUT, lpos,(LPVOID) lpv, dwCount );
  2358. }
  2359. //+---------------------------------------------------------------------------
  2360. //
  2361. // Function: Thop_OLESTREAM_1632, public
  2362. //
  2363. // Synopsis: Thunks an OLESTREAM parameter from 16-bit to 32-bit
  2364. //
  2365. // Arguments: [pti] - Thunk state information
  2366. //
  2367. // Returns: Appropriate status code
  2368. //
  2369. // History: 14-Mar-94 BobDay Created
  2370. //
  2371. //----------------------------------------------------------------------------
  2372. _OLESTREAMVTBL osVtbl =
  2373. {
  2374. OLESTREAM_Get_Proxy,
  2375. OLESTREAM_Put_Proxy
  2376. };
  2377. DWORD Thop_OLESTREAM_1632(THUNKINFO *pti)
  2378. {
  2379. OLESTREAMOBJECT osObject;
  2380. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_OLESTREAM);
  2381. //
  2382. // Ignore the THOP_INPUT/THOP_OUTPUT, it is always just an interface
  2383. //
  2384. osObject.os.lpstbl = &osVtbl;
  2385. GET_STACK16(pti, osObject.vpolestream16, VPVOID);
  2386. TO_STACK32(pti, &osObject, LPOLESTREAMOBJECT );
  2387. pti->pThop++;
  2388. return EXECUTE_THOP1632(pti);
  2389. }
  2390. //+---------------------------------------------------------------------------
  2391. //
  2392. // Function: Thop_RPCOLEMESSAGE_1632, public
  2393. //
  2394. // Synopsis: Converts 16-bit RPCOLEMESSAGE to 32-bit RPCOLEMESSAGE
  2395. //
  2396. // Arguments: [pti] - Thunk state information
  2397. //
  2398. // Returns: Appropriate status code
  2399. //
  2400. // History: 23-Feb-94 BobDay Created
  2401. // 28-May-94 JohannP Rewritten
  2402. // 13-Aug-94 Rickhi made it work for GetBuffer when the
  2403. // buffer size grows, commented better
  2404. //
  2405. // CODEWORK: this routine is inefficient. since it cant tell why it was
  2406. // called (GetBuffer/SendReceive/Invoke/FreeBuffer) it always
  2407. // copies the data, when it only really needs to in Invoke and
  2408. // in SendReceive.
  2409. //
  2410. // Context: This routine will "Thop" a client side RPCOLEMESSGE (aka "rom")
  2411. // three times. The first time for the "getbuffer" call, the second
  2412. // time for the "SendRecieve", and the third time for the "freebuffer".
  2413. // This make it confusing, some calls allocate a buffer but don't
  2414. // free it. Other calls free a buffer they didn't allocate. A good
  2415. // way to see what is happening is to step through several calls to
  2416. // this routine with a debugger and note the pointer values.
  2417. //
  2418. //----------------------------------------------------------------------------
  2419. DWORD Thop_RPCOLEMESSAGE_1632( THUNKINFO *pti )
  2420. {
  2421. DWORD dwResult;
  2422. PRPCOLEMESSAGE prom32;
  2423. VPVOID vprom16;
  2424. RPCOLEMESSAGE UNALIGNED *prom16;
  2425. LPVOID lp16;
  2426. RPCOLEMESSAGE rom32;
  2427. BOOL fAllocNew = FALSE;
  2428. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_RPCOLEMESSAGE);
  2429. //
  2430. // We currently have only INOUT RPCOLEMESSAGE
  2431. //
  2432. thkAssert( (*pti->pThop & THOP_IOMASK) == (THOP_IN | THOP_OUT) &&
  2433. "RPCOLEMESSAGE must be input/output only" );
  2434. //
  2435. // Processing for a RPCOLEMESSAGE FAR * as input/output
  2436. //
  2437. GET_STACK16(pti, vprom16, VPVOID);
  2438. prom32 = NULL;
  2439. if ( vprom16 != 0 )
  2440. {
  2441. // Copy over the input RPCOLEMESSAGE structure
  2442. prom16 = (RPCOLEMESSAGE UNALIGNED *)
  2443. GetReadWritePtr16( pti, vprom16, sizeof(RPCOLEMESSAGE) );
  2444. if ( prom16 != NULL )
  2445. {
  2446. // Note: ROM_THUNK_FIELD(prom) holds the pointer to the 32 bit rom
  2447. // in case the buffer is not NULL
  2448. // Note: this assert is not valid when a fault happens on the
  2449. // server side. In that case, the return buffer is NULLed
  2450. // by the 16bit stub but the THUNK_FIELD is non-null.
  2451. //thkAssert((prom16->Buffer == NULL &&
  2452. // ROM_THUNK_FIELD(prom16) == NULL) ||
  2453. // (prom16->Buffer != NULL &&
  2454. // ROM_THUNK_FIELD(prom16) != NULL));
  2455. if (prom16->Buffer != NULL)
  2456. {
  2457. prom32 = (RPCOLEMESSAGE *)ROM_THUNK_FIELD(prom16);
  2458. if ( prom32->Buffer != NULL )
  2459. {
  2460. // we use the min size of the two buffers because when
  2461. // the stub (server side) calls GetBuffer he is supplying
  2462. // the old pBuffer with the new (and potentially larger)
  2463. // cbBuffer
  2464. DWORD cbSizeMin = (prom16->cbBuffer <= prom32->cbBuffer) ?
  2465. prom16->cbBuffer : prom32->cbBuffer;
  2466. lp16 = (LPVOID)GetReadPtr16(pti,
  2467. (VPVOID)prom16->Buffer,
  2468. cbSizeMin);
  2469. if (lp16 == NULL)
  2470. {
  2471. prom32 = NULL;
  2472. }
  2473. else
  2474. {
  2475. memcpy( prom32->Buffer, lp16, prom32->cbBuffer );
  2476. WOWRELVDMPTR((VPVOID)prom16->Buffer);
  2477. }
  2478. }
  2479. if (prom32)
  2480. {
  2481. // the stub might be asking for a larger buffer for output
  2482. // parameters than it was given for input parameters. We have
  2483. // to figure that out here by comparing the 16bit size with
  2484. // the 32bit size.
  2485. fAllocNew = (prom32->cbBuffer < prom16->cbBuffer);
  2486. prom32->cbBuffer = prom16->cbBuffer;
  2487. }
  2488. else
  2489. {
  2490. fAllocNew = FALSE;
  2491. }
  2492. }
  2493. else
  2494. {
  2495. rom32 = *prom16;
  2496. prom32 = &rom32;
  2497. }
  2498. WOWRELVDMPTR(vprom16);
  2499. }
  2500. }
  2501. TO_STACK32(pti, prom32, PRPCOLEMESSAGE);
  2502. pti->pThop++;
  2503. dwResult = EXECUTE_THOP1632(pti);
  2504. if ( prom32 != NULL )
  2505. {
  2506. prom16 = (RPCOLEMESSAGE UNALIGNED *)
  2507. GetReadWritePtr16( pti, vprom16, sizeof(RPCOLEMESSAGE) );
  2508. if ( prom16 == NULL )
  2509. {
  2510. dwResult = (DWORD)E_UNEXPECTED;
  2511. }
  2512. else
  2513. {
  2514. if (SUCCEEDED(dwResult))
  2515. {
  2516. if (prom32->Buffer == NULL)
  2517. {
  2518. // RELEASE THE BUFFER AND ROM:
  2519. // Free the 16 bit buffer, copy the 32 bit rom into
  2520. // the 16 bit rom and free the 32bit rom, if it was
  2521. // allocated
  2522. //
  2523. if (prom16->Buffer != 0)
  2524. {
  2525. TaskFree16((VPVOID)prom16->Buffer);
  2526. }
  2527. *prom16 = *prom32;
  2528. if (prom32 != &rom32)
  2529. {
  2530. TaskFree32(prom32);
  2531. prom32 = NULL;
  2532. }
  2533. ROM_THUNK_FIELD(prom16) = NULL;
  2534. }
  2535. else
  2536. {
  2537. // ALLOCATE AND/OR COPYBACK THE BUFFER AND ROM:
  2538. RPCOLEMESSAGE *pr32;
  2539. LPVOID pBuffer;
  2540. // Create a message to save the 32-bit message in
  2541. // Use the existing one in the thunk field if we can
  2542. if (ROM_THUNK_FIELD(prom16) == NULL)
  2543. {
  2544. pr32 = (RPCOLEMESSAGE *)
  2545. TaskMalloc32(sizeof(RPCOLEMESSAGE));
  2546. }
  2547. else
  2548. {
  2549. pr32 = (RPCOLEMESSAGE *)ROM_THUNK_FIELD(prom16);
  2550. }
  2551. *pr32 = *prom32;
  2552. //
  2553. // Allocate an output buffer and copy the buffer back
  2554. //
  2555. if ( (prom16->Buffer == NULL)
  2556. || (prom16->cbBuffer < prom32->cbBuffer)
  2557. || fAllocNew)
  2558. {
  2559. if (prom16->Buffer != NULL)
  2560. {
  2561. TaskFree16((VPVOID) prom16->Buffer);
  2562. }
  2563. pBuffer = (LPVOID)TaskMalloc16(prom32->cbBuffer );
  2564. }
  2565. else
  2566. {
  2567. pBuffer = prom16->Buffer;
  2568. }
  2569. *prom16 = *prom32;
  2570. prom16->Buffer = pBuffer;
  2571. ROM_THUNK_FIELD(prom16) = pr32;
  2572. if (prom16->Buffer == NULL)
  2573. {
  2574. dwResult = (DWORD)E_OUTOFMEMORY;
  2575. }
  2576. else
  2577. {
  2578. lp16 = (LPVOID)GetReadPtr16(pti,
  2579. (VPVOID)prom16->Buffer,
  2580. prom16->cbBuffer);
  2581. if ( lp16 == NULL )
  2582. {
  2583. dwResult = (DWORD)E_UNEXPECTED;
  2584. }
  2585. else
  2586. {
  2587. memcpy( lp16, prom32->Buffer,
  2588. prom32->cbBuffer );
  2589. WOWRELVDMPTR((VPVOID)prom16->Buffer);
  2590. }
  2591. }
  2592. }
  2593. }
  2594. WOWRELVDMPTR(vprom16);
  2595. }
  2596. }
  2597. return dwResult;
  2598. }
  2599. //+---------------------------------------------------------------------------
  2600. //
  2601. // Function: Thop_ALIAS32_1632, public
  2602. //
  2603. // Synopsis: Handles 16-bit aliases to 32-bit quantities
  2604. //
  2605. // Arguments: [pti] - Thunking state information
  2606. //
  2607. // Returns: Appropriate status code
  2608. //
  2609. // History: 27-May-94 DrewB Created
  2610. //
  2611. //----------------------------------------------------------------------------
  2612. DWORD Thop_ALIAS32_1632(THUNKINFO *pti)
  2613. {
  2614. ALIAS alias;
  2615. DWORD dwValue;
  2616. THOP thopAction;
  2617. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_ALIAS32);
  2618. thkAssert((*pti->pThop & THOP_IOMASK) == 0);
  2619. pti->pThop++;
  2620. GET_STACK16(pti, alias, ALIAS);
  2621. // Second byte indicates how the alias should be handled
  2622. thopAction = *pti->pThop++;
  2623. if (alias != 0)
  2624. {
  2625. switch(thopAction)
  2626. {
  2627. case ALIAS_RESOLVE:
  2628. dwValue = gAliases32.AliasValue(alias);
  2629. break;
  2630. case ALIAS_REMOVE:
  2631. dwValue = gAliases32.AliasValue(alias);
  2632. gAliases32.RemoveAlias(alias);
  2633. break;
  2634. default:
  2635. thkAssert(!"Default hit in Thop_ALIAS32_1632");
  2636. dwValue = 0;
  2637. break;
  2638. }
  2639. }
  2640. else
  2641. {
  2642. dwValue = 0;
  2643. }
  2644. thkDebugOut((DEB_ARGS, "In1632 ALIAS32: 0x%04X -> 0x%08lX\n",
  2645. alias, dwValue));
  2646. TO_STACK32(pti, dwValue, DWORD);
  2647. return EXECUTE_THOP1632(pti);
  2648. }
  2649. //+---------------------------------------------------------------------------
  2650. //
  2651. // Function: Thop_ENUM_1632, public
  2652. //
  2653. // Synopsis: Thunks Enum::Next parameters
  2654. //
  2655. // Arguments: [pti] - Thunk state information
  2656. //
  2657. // Returns: Appropriate status code
  2658. //
  2659. // History: 1-Mar-94 BobDay Created
  2660. //
  2661. // Notes: This thunk is the start of a 2-byte thop. The next thop
  2662. // byte references a function in the enumerator table, rather
  2663. // than the standard thop table.
  2664. //
  2665. //----------------------------------------------------------------------------
  2666. DWORD Thop_ENUM_1632(THUNKINFO *pti)
  2667. {
  2668. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_ENUM);
  2669. thkAssert((*pti->pThop & THOP_IOMASK) == 0);
  2670. //
  2671. // Get then next thop byte and execute it as a Enum thop
  2672. //
  2673. pti->pThop++;
  2674. return EXECUTE_ENUMTHOP1632(pti);
  2675. }
  2676. //+---------------------------------------------------------------------------
  2677. //
  2678. // Function: CallbackProcessing_1632, public
  2679. //
  2680. // Synopsis: Thunks IOleObject::Draw pfnContinue & DWORD parameters
  2681. //
  2682. // Arguments: [pti] - Thunk state information
  2683. //
  2684. // Returns: Appropriate status code
  2685. //
  2686. // History: 3-Mar-94 BobDay Created
  2687. //
  2688. //----------------------------------------------------------------------------
  2689. typedef struct tagCallbackControl
  2690. {
  2691. DWORD dwContinue;
  2692. VPVOID vpfn16;
  2693. } CALLBACKCONTROL;
  2694. BOOL CallbackProcessing_1632( DWORD dwContinue )
  2695. {
  2696. DWORD dwResult;
  2697. CALLBACKCONTROL *lpcbc;
  2698. lpcbc = (CALLBACKCONTROL *)dwContinue;
  2699. // The callback function must be FAR PASCAL
  2700. // It's declared CALLBACK in the methods so this is ensured
  2701. dwResult = CallbackTo16( lpcbc->vpfn16, lpcbc->dwContinue );
  2702. return (BOOL)((WORD)dwResult); // Ignore HIWORD
  2703. }
  2704. //+---------------------------------------------------------------------------
  2705. //
  2706. // Function: Thop_CALLBACK_1632, public
  2707. //
  2708. // Synopsis: Thunks IOleObject::Draw pfnContinue & DWORD parameters
  2709. //
  2710. // Arguments: [pti] - Thunk state information
  2711. //
  2712. // Returns: Appropriate status code
  2713. //
  2714. // History: 3-Mar-94 BobDay Created
  2715. //
  2716. //----------------------------------------------------------------------------
  2717. DWORD Thop_CALLBACK_1632(THUNKINFO *pti)
  2718. {
  2719. VPVOID vpfn16;
  2720. DWORD dwContinue;
  2721. CALLBACKCONTROL cbc;
  2722. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_CALLBACK);
  2723. thkAssert((*pti->pThop & THOP_IOMASK) == 0);
  2724. GET_STACK16(pti, vpfn16, VPVOID);
  2725. GET_STACK16(pti, dwContinue, DWORD);
  2726. if ( vpfn16 == 0 )
  2727. {
  2728. TO_STACK32(pti, NULL, LPVOID);
  2729. TO_STACK32(pti, dwContinue, DWORD);
  2730. }
  2731. else
  2732. {
  2733. cbc.vpfn16 = vpfn16;
  2734. cbc.dwContinue = dwContinue;
  2735. TO_STACK32(pti, CallbackProcessing_1632, LPVOID);
  2736. TO_STACK32(pti, (DWORD)&cbc, DWORD);
  2737. }
  2738. pti->pThop++;
  2739. return EXECUTE_THOP1632(pti);
  2740. }
  2741. //+---------------------------------------------------------------------------
  2742. //
  2743. // Function: Thop_CLSCONTEXT_1632, public
  2744. //
  2745. // Synopsis: Converts a class context flags DWORD
  2746. //
  2747. // Arguments: [pti] - Thunk state information
  2748. //
  2749. // Returns: Appropriate status code
  2750. //
  2751. // History: 29-Jun-94 DrewB Created
  2752. //
  2753. //----------------------------------------------------------------------------
  2754. DWORD Thop_CLSCONTEXT_1632(THUNKINFO *pti)
  2755. {
  2756. DWORD dwClsContext;
  2757. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_CLSCONTEXT);
  2758. thkAssert((*pti->pThop & THOP_IOMASK) == 0);
  2759. GET_STACK16(pti, dwClsContext, DWORD);
  2760. // When passing a 16-bit class context on to 32-bits,
  2761. // add on a flag to indicate that this is a 16-bit request
  2762. // in the inproc server case
  2763. if (dwClsContext & CLSCTX_INPROC_SERVER)
  2764. {
  2765. dwClsContext |= CLSCTX_INPROC_SERVER16;
  2766. }
  2767. TO_STACK32(pti, dwClsContext, DWORD);
  2768. pti->pThop++;
  2769. return EXECUTE_THOP1632(pti);
  2770. }
  2771. //+---------------------------------------------------------------------------
  2772. //
  2773. // Function: Thop_FILENAME_1632, public
  2774. //
  2775. // Synopsis: Converts a filename string
  2776. //
  2777. // Arguments: [pti] - Thunk state information
  2778. //
  2779. // Returns: Appropriate status code
  2780. //
  2781. // History: 24-Aug-94 DrewB Created
  2782. //
  2783. //----------------------------------------------------------------------------
  2784. DWORD Thop_FILENAME_1632(THUNKINFO *pti)
  2785. {
  2786. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_FILENAME);
  2787. // Can be in or out only
  2788. thkAssert((*pti->pThop & THOP_IOMASK) == THOP_IN ||
  2789. (*pti->pThop & THOP_IOMASK) == THOP_OUT);
  2790. if ((*pti->pThop & THOP_IN) != 0)
  2791. {
  2792. // No special processing is necessary for filenames going
  2793. // from 16->32 since it isn't possible for 16-bit code to
  2794. // generate a filename which can't be handled in 32-bits
  2795. return ThunkInString1632(pti);
  2796. }
  2797. else
  2798. {
  2799. thkAssert((*pti->pThop & THOP_OUT) != 0);
  2800. // Convert filenames going from 32->16 to short filenames
  2801. // to avoid any possible problems with non-8.3 names.
  2802. return ThunkOutString1632(pti, TRUE);
  2803. }
  2804. }
  2805. //+---------------------------------------------------------------------------
  2806. //
  2807. // Function: Thop_SIZEDSTRING_1632, public
  2808. //
  2809. // Synopsis: Converts strings which cannot exceed a given length
  2810. //
  2811. // Arguments: [pti] - Thunk state information
  2812. //
  2813. // Returns: Appropriate status code
  2814. //
  2815. // History: 02-Sep-94 DrewB Created
  2816. //
  2817. //----------------------------------------------------------------------------
  2818. DWORD Thop_SIZEDSTRING_1632(THUNKINFO *pti)
  2819. {
  2820. thkAssert((*pti->pThop & THOP_OPMASK) == THOP_SIZEDSTRING);
  2821. thkAssert((*pti->pThop & THOP_IOMASK) == THOP_IN);
  2822. // For 16->32, there are no limits on string length so
  2823. // thunk the string normally
  2824. // Advance once to account for the length byte
  2825. // ThunkInString will advance again
  2826. pti->pThop++;
  2827. return ThunkInString1632(pti);
  2828. }
  2829. #define THOP_FN(x) Thop_ ## x ## _1632
  2830. DWORD (*CONST aThopFunctions1632[])(THUNKINFO *) =
  2831. {
  2832. // x = Implemented
  2833. // ? = Mysteriously not needed
  2834. // = Left to do
  2835. //
  2836. // ^
  2837. // |
  2838. // +===+
  2839. // |
  2840. // v
  2841. //
  2842. ThunkCall1632, // x Terminating THOP
  2843. Thop_ShortToLong_1632, // x SHORTLONG
  2844. Thop_WordToDword_1632, // x WORDDWORD
  2845. Thop_Copy_1632, // x COPY
  2846. THOP_FN(LPSTR), // x LPSTR
  2847. THOP_FN(LPLPSTR), // x LPLPSTR
  2848. THOP_FN(BUFFER), // x BUFFER
  2849. Thop_UserHandle_1632, // x HUSER
  2850. Thop_GdiHandle_1632, // x HGDI
  2851. THOP_FN(SIZE), // x SIZE
  2852. THOP_FN(RECT), // x RECT
  2853. THOP_FN(MSG), // x MSG
  2854. THOP_FN(HRESULT), // x HRESULT
  2855. THOP_FN(STATSTG), // x STATSTG
  2856. THOP_FN(DVTARGETDEVICE), // x DVTARGETDEVICE
  2857. THOP_FN(STGMEDIUM), // x STGMEDIUM
  2858. THOP_FN(FORMATETC), // x FORMATETC
  2859. THOP_FN(HACCEL), // x HACCEL
  2860. THOP_FN(OIFI), // x OLEINPLACEFRAMEINFO
  2861. THOP_FN(BINDOPTS), // x BIND_OPTS
  2862. THOP_FN(LOGPALETTE), // x LOGPALETTE
  2863. THOP_FN(SNB), // x SNB
  2864. THOP_FN(CRGIID), // x CRGIID
  2865. THOP_FN(OLESTREAM), // x OLESTREAM
  2866. THOP_FN(HTASK), // x HTASK
  2867. THOP_FN(INTERFACEINFO), // x INTERFACEINFO
  2868. THOP_FN(IFACE), // x IFACE
  2869. THOP_FN(IFACE), // x IFACEOWNER
  2870. THOP_FN(IFACE), // x IFACENOADDREF
  2871. Thop_ERROR_1632, // x IFACECLEAN
  2872. THOP_FN(IFACEGEN), // x IFACEGEN
  2873. THOP_FN(IFACEGEN), // x IFACEGENOWNER
  2874. THOP_FN(IFACE), // x UNKOUTER
  2875. Thop_ERROR_1632, // x UNKINNER
  2876. Thop_ERROR_1632, // x ROUTINE_INDEX
  2877. THOP_FN(RETURNTYPE), // x RETURN_TYPE
  2878. THOP_FN(NULL), // x NULL
  2879. Thop_ERROR_1632, // x ERROR
  2880. THOP_FN(ENUM), // x ENUM
  2881. THOP_FN(CALLBACK), // x CALLBACK
  2882. THOP_FN(RPCOLEMESSAGE), // x RPCOLEMESSAGE
  2883. THOP_FN(ALIAS32), // x ALIAS32
  2884. THOP_FN(CLSCONTEXT), // x CLSCONTEXT
  2885. THOP_FN(FILENAME), // x FILENAME
  2886. THOP_FN(SIZEDSTRING), // x SIZEDSTRING
  2887. };
  2888. //+---------------------------------------------------------------------------
  2889. //
  2890. // Function: General_Enum_1632, private
  2891. //
  2892. // Synopsis: Thunking for standard OLE enumerator interface ::Next member
  2893. // function.
  2894. //
  2895. // Arguments: [pti] - Thunk state information
  2896. // [uiSize32] - 32-bit information size
  2897. // [uiSize16] - 16-bit information size
  2898. // [pfnCallback] - Data thunking callback
  2899. // [pfnCleanup] - Thunking cleanup
  2900. //
  2901. // Returns: Appropriate status code
  2902. //
  2903. // History: 1-Mar-94 BobDay Created
  2904. //
  2905. // Notes: This handler is called from many IXXXEnum::Next handlers thop
  2906. // thunks to do the standard sorts of "buffer of structures"
  2907. // processing.
  2908. //
  2909. //----------------------------------------------------------------------------
  2910. #define MAX_ALLOCA_STRUCT 10
  2911. DWORD General_Enum_1632(
  2912. THUNKINFO *pti,
  2913. UINT uiSize32,
  2914. UINT uiSize16,
  2915. SCODE (*pfnCallback)( THUNKINFO *, LPVOID, VPVOID),
  2916. void (*pfnCleanup)( THUNKINFO *, LPVOID, VPVOID) )
  2917. {
  2918. DWORD dwResult;
  2919. ULONG ulCount;
  2920. VPVOID vpstruct16;
  2921. VPVOID vpfetched16;
  2922. LPVOID lpstruct32;
  2923. LPVOID lpstruct32Iterate;
  2924. VPVOID vpstruct16Iterate;
  2925. ULONG ulFetched32;
  2926. ULONG *lpfetched32;
  2927. ULONG UNALIGNED *lpfetched16;
  2928. ULONG ulIterate;
  2929. LPVOID lp16;
  2930. BOOL fError;
  2931. SCODE sc;
  2932. dwResult = (DWORD)S_OK;
  2933. GET_STACK16(pti, ulCount, ULONG );
  2934. GET_STACK16(pti, vpstruct16, VPVOID );
  2935. GET_STACK16(pti, vpfetched16, VPVOID );
  2936. //
  2937. // THIS ROUTINE CAN DEAL WITH dwResult RATHER THAN pti->scResult BECAUSE
  2938. // WE KNOW THIS IS THE ONLY THOP FOR THIS FUNCTION! NO OTHER CLEANUP
  2939. // WILL HAVE TO BE DONE!
  2940. //
  2941. ulFetched32 = 0;
  2942. lpfetched32 = &ulFetched32;
  2943. lp16 = NULL;
  2944. lpstruct32 = NULL;
  2945. if ( vpstruct16 != 0 )
  2946. {
  2947. if ( ulCount == 0 )
  2948. {
  2949. dwResult = (DWORD)E_INVALIDARG;
  2950. }
  2951. else
  2952. {
  2953. //
  2954. // Verify we have write access to the 16-bit memory.
  2955. //
  2956. lp16 = GetWritePtr16(pti, vpstruct16, uiSize16*ulCount);
  2957. if ( lp16 == NULL )
  2958. {
  2959. dwResult = (DWORD)E_INVALIDARG;
  2960. }
  2961. else
  2962. {
  2963. if ( ulCount > MAX_ALLOCA_STRUCT )
  2964. {
  2965. lpstruct32 = (LPVOID)CoTaskMemAlloc( ulCount * uiSize32 );
  2966. if (lpstruct32 == NULL)
  2967. {
  2968. dwResult = (DWORD)E_OUTOFMEMORY;
  2969. }
  2970. }
  2971. else
  2972. {
  2973. lpstruct32 = (LPVOID)STACKALLOC32( ulCount * uiSize32 );
  2974. if (lpstruct32 == NULL)
  2975. {
  2976. dwResult = (DWORD)E_OUTOFMEMORY;
  2977. }
  2978. }
  2979. WOWRELVDMPTR(vpstruct16);
  2980. }
  2981. }
  2982. }
  2983. if (SUCCEEDED(dwResult))
  2984. {
  2985. TO_STACK32(pti, ulCount, ULONG);
  2986. TO_STACK32(pti, lpstruct32, LPVOID);
  2987. TO_STACK32(pti, lpfetched32, ULONG FAR *);
  2988. pti->pThop++;
  2989. dwResult = EXECUTE_THOP1632(pti);
  2990. }
  2991. if ( SUCCEEDED(dwResult) )
  2992. {
  2993. if ( vpstruct16 != 0 )
  2994. {
  2995. // Some apps (MsWorks3 is one) return S_FALSE and do not return
  2996. // the number of elements retrieved. The only thing we can
  2997. // do is ignore the enumeration since we don't know how many
  2998. // were actually set. Of course, we can't ignore all enumerations
  2999. // when the return is S_FALSE so we only handle the case
  3000. // where S_FALSE was returned on a enumeration of one element,
  3001. // in which we can be sure there isn't any valid data
  3002. if (dwResult == (DWORD)S_FALSE && ulCount == 1)
  3003. {
  3004. ulFetched32 = 0;
  3005. }
  3006. //
  3007. // Iterate through all of the structures, converting them
  3008. // into 16-bit
  3009. //
  3010. fError = FALSE;
  3011. ulIterate = 0;
  3012. vpstruct16Iterate = vpstruct16;
  3013. lpstruct32Iterate = lpstruct32;
  3014. while ( ulIterate < ulFetched32 )
  3015. {
  3016. //
  3017. // Callback to the callback function to do any specific
  3018. // processing
  3019. //
  3020. sc = (*pfnCallback)( pti, lpstruct32Iterate,
  3021. vpstruct16Iterate );
  3022. if ( FAILED(sc) )
  3023. {
  3024. fError = TRUE;
  3025. dwResult = sc;
  3026. }
  3027. vpstruct16Iterate = (VPVOID)((DWORD)vpstruct16Iterate +
  3028. uiSize16);
  3029. lpstruct32Iterate = (LPVOID)((DWORD)lpstruct32Iterate +
  3030. uiSize32);
  3031. ulIterate++;
  3032. }
  3033. if ( fError )
  3034. {
  3035. //
  3036. // Cleanup all these guys
  3037. //
  3038. ulIterate = 0;
  3039. vpstruct16Iterate = vpstruct16;
  3040. lpstruct32Iterate = lpstruct32;
  3041. while ( ulIterate <= ulFetched32 )
  3042. {
  3043. (*pfnCleanup)( pti, lpstruct32Iterate, vpstruct16Iterate );
  3044. vpstruct16Iterate = (VPVOID)((DWORD)vpstruct16Iterate +
  3045. uiSize16);
  3046. lpstruct32Iterate = (LPVOID)((DWORD)lpstruct32Iterate +
  3047. uiSize32);
  3048. ulIterate++;
  3049. }
  3050. }
  3051. }
  3052. }
  3053. if (FAILED(dwResult) && lp16 != NULL)
  3054. {
  3055. memset(lp16, 0, ulCount*uiSize16);
  3056. }
  3057. //
  3058. // Free up any space we've allocated
  3059. //
  3060. if (lpstruct32 != NULL)
  3061. {
  3062. if ( ulCount > MAX_ALLOCA_STRUCT )
  3063. {
  3064. CoTaskMemFree( lpstruct32 );
  3065. }
  3066. else
  3067. {
  3068. STACKFREE32(lpstruct32, ulCount*uiSize32);
  3069. }
  3070. }
  3071. if ( vpfetched16 != 0 )
  3072. {
  3073. lpfetched16 = FIXVDMPTR( vpfetched16, ULONG);
  3074. *lpfetched16 = ulFetched32;
  3075. RELVDMPTR(vpfetched16);
  3076. }
  3077. return dwResult;
  3078. }
  3079. //+---------------------------------------------------------------------------
  3080. //
  3081. // Function: Callback_STRING_1632, public
  3082. //
  3083. // Synopsis: Prepares the LPOLESTR for the copy back into 16-bit address
  3084. // space.
  3085. //
  3086. // Arguments: [pti] - Thunking state information
  3087. // [lp32] - Pointer to 32-bit returned structure
  3088. // [lp16] - Pointer to 16-bit output structure
  3089. //
  3090. // Returns: SCODE indicating success/failure
  3091. //
  3092. // History: 1-Mar-94 BobDay Created
  3093. //
  3094. //----------------------------------------------------------------------------
  3095. SCODE Callback_STRING_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3096. {
  3097. VPSTR vpstr;
  3098. VPSTR UNALIGNED *pvpstr16;
  3099. SCODE sc;
  3100. vpstr = 0;
  3101. sc = ConvertTaskString3216(pti, *(LPOLESTR *)lp32, NULL, 0,
  3102. &vpstr);
  3103. pvpstr16 = FIXVDMPTR(vp16, VPSTR);
  3104. *pvpstr16 = vpstr;
  3105. RELVDMPTR(vp16);
  3106. return sc;
  3107. }
  3108. //+---------------------------------------------------------------------------
  3109. //
  3110. // Function: Cleanup_STRING_1632, public
  3111. //
  3112. // Synopsis: Cleans up the any STRINGs returned (either to 16-bit or 32-bit)
  3113. //
  3114. // Arguments: [pti] - Thunking state information
  3115. // [lp32] - Pointer to 32-bit returned structure
  3116. // [lp16] - Pointer to 16-bit output structure
  3117. //
  3118. // Returns: nothing, should NEVER fail
  3119. //
  3120. // History: 1-Mar-94 BobDay Created
  3121. //
  3122. //----------------------------------------------------------------------------
  3123. void Cleanup_STRING_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3124. {
  3125. VPSTR UNALIGNED *lpvpstr16;
  3126. VPSTR vpstr16;
  3127. lpvpstr16 = FIXVDMPTR( vp16, VPSTR );
  3128. vpstr16 = *lpvpstr16;
  3129. RELVDMPTR(vp16);
  3130. if ( vpstr16 != 0 )
  3131. {
  3132. TaskFree16( vpstr16 );
  3133. }
  3134. }
  3135. //+---------------------------------------------------------------------------
  3136. //
  3137. // Function: Thop_Enum_STRING_1632, public
  3138. //
  3139. // Synopsis: Thunks IEnumSTRING::Next parameters
  3140. //
  3141. // Arguments: [pti] - Thunk state information
  3142. //
  3143. // Returns: Appropriate status code
  3144. //
  3145. // History: 1-Mar-94 BobDay Created
  3146. //
  3147. // Notes: This thunk is 2nd part of a 2-byte thop.
  3148. //
  3149. //----------------------------------------------------------------------------
  3150. DWORD Thop_Enum_STRING_1632(THUNKINFO *pti)
  3151. {
  3152. return General_Enum_1632(pti,
  3153. sizeof(LPOLESTR),
  3154. sizeof(VPSTR),
  3155. Callback_STRING_1632,
  3156. Cleanup_STRING_1632 );
  3157. }
  3158. //+---------------------------------------------------------------------------
  3159. //
  3160. // Function: Callback_UNKNOWN_1632, public
  3161. //
  3162. // Synopsis: Prepares the UNKNOWN structure for the copy back into 16-bit
  3163. // address space.
  3164. //
  3165. // Arguments: [pti] - Thunking state information
  3166. // [lp32] - Pointer to 32-bit returned structure
  3167. // [lp16] - Pointer to 16-bit output structure
  3168. //
  3169. // Returns: SCODE indicating success/failure
  3170. //
  3171. // History: 1-Mar-94 BobDay Created
  3172. //
  3173. //----------------------------------------------------------------------------
  3174. SCODE Callback_UNKNOWN_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3175. {
  3176. VPVOID vpunknown16;
  3177. SCODE sc = S_OK;
  3178. vpunknown16 =
  3179. pti->pThkMgr->FindProxy1632(NULL, *(LPUNKNOWN *)lp32, NULL,
  3180. INDEX_IIDIDX(THI_IUnknown), NULL);
  3181. // Release the actual 32-bit IUnknown as it is a OUT parameter
  3182. // This could be the last release on the interface if the
  3183. // above call failed;
  3184. (*((LPUNKNOWN *) lp32))->Release();
  3185. if(!vpunknown16) {
  3186. sc = E_OUTOFMEMORY;
  3187. }
  3188. *FIXVDMPTR( vp16, VPVOID ) = vpunknown16;
  3189. RELVDMPTR(vp16);
  3190. return sc;
  3191. }
  3192. //+---------------------------------------------------------------------------
  3193. //
  3194. // Function: Cleanup_UNKNOWN_1632, public
  3195. //
  3196. // Synopsis: Cleans up the any UNKNOWNs returned (either to 16-bit
  3197. // or 32-bit)
  3198. //
  3199. // Arguments: [pti] - Thunking state information
  3200. // [lp32] - Pointer to 32-bit returned structure
  3201. // [lp16] - Pointer to 16-bit output structure
  3202. //
  3203. // Returns: nothing, should NEVER fail
  3204. //
  3205. // History: 1-Mar-94 BobDay Created
  3206. //
  3207. //----------------------------------------------------------------------------
  3208. void Cleanup_UNKNOWN_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3209. {
  3210. LPUNKNOWN lpunknown32;
  3211. VPVOID vpunknown16;
  3212. vpunknown16 = *FIXVDMPTR( vp16, VPVOID );
  3213. RELVDMPTR(vp16);
  3214. lpunknown32 = *(LPUNKNOWN *)lp32;
  3215. if(vpunknown16) {
  3216. // Release the proxy to 32-bit interface
  3217. pti->pThkMgr->ReleaseProxy1632(vpunknown16);
  3218. }
  3219. }
  3220. //+---------------------------------------------------------------------------
  3221. //
  3222. // Function: Thop_Enum_UNKNOWN_1632, public
  3223. //
  3224. // Synopsis: Thunks IEnumUNKNOWN::Next parameters
  3225. //
  3226. // Arguments: [pti] - Thunk state information
  3227. //
  3228. // Returns: Appropriate status code
  3229. //
  3230. // History: 1-Mar-94 BobDay Created
  3231. //
  3232. // Notes: This thunk is 2nd part of a 2-byte thop.
  3233. //
  3234. //----------------------------------------------------------------------------
  3235. DWORD Thop_Enum_UNKNOWN_1632(THUNKINFO *pti)
  3236. {
  3237. return General_Enum_1632(pti,
  3238. sizeof(LPUNKNOWN),
  3239. sizeof(LPUNKNOWN),
  3240. Callback_UNKNOWN_1632,
  3241. Cleanup_UNKNOWN_1632 );
  3242. }
  3243. //+---------------------------------------------------------------------------
  3244. //
  3245. // Function: Callback_STATSTG_1632, public
  3246. //
  3247. // Synopsis: Prepares the STATSTG structure for the copy back into 16-bit
  3248. // address space.
  3249. //
  3250. // Arguments: [pti] - Thunking state information
  3251. // [lp32] - Pointer to 32-bit returned structure
  3252. // [lp16] - Pointer to 16-bit output structure
  3253. //
  3254. // Returns: SCODE indicating success/failure
  3255. //
  3256. // History: 1-Mar-94 BobDay Created
  3257. //
  3258. //----------------------------------------------------------------------------
  3259. SCODE Callback_STATSTG_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3260. {
  3261. (FIXVDMPTR(vp16, STATSTG))->pwcsName = NULL;
  3262. RELVDMPTR(vp16);
  3263. return ConvertStatStg3216(pti, (STATSTG *)lp32, vp16,
  3264. NULL, 0);
  3265. }
  3266. //+---------------------------------------------------------------------------
  3267. //
  3268. // Function: Cleanup_STATSTG_1632, public
  3269. //
  3270. // Synopsis: Cleans up the any STATSTGs returned (either to 16-bit
  3271. // or 32-bit)
  3272. //
  3273. // Arguments: [pti] - Thunking state information
  3274. // [lp32] - Pointer to 32-bit returned structure
  3275. // [lp16] - Pointer to 16-bit output structure
  3276. //
  3277. // Returns: nothing, should NEVER fail
  3278. //
  3279. // History: 1-Mar-94 BobDay Created
  3280. //
  3281. //----------------------------------------------------------------------------
  3282. void Cleanup_STATSTG_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3283. {
  3284. STATSTG UNALIGNED *lpstatstg16;
  3285. VPVOID vpstr;
  3286. lpstatstg16 = FIXVDMPTR( vp16, STATSTG );
  3287. vpstr = (VPVOID)lpstatstg16->pwcsName;
  3288. RELVDMPTR(vp16);
  3289. if ( vpstr != 0)
  3290. {
  3291. TaskFree16( vpstr );
  3292. }
  3293. }
  3294. //+---------------------------------------------------------------------------
  3295. //
  3296. // Function: Thop_Enum_STATSTG_1632, public
  3297. //
  3298. // Synopsis: Thunks IEnumSTATSTG::Next parameters
  3299. //
  3300. // Arguments: [pti] - Thunk state information
  3301. //
  3302. // Returns: Appropriate status code
  3303. //
  3304. // History: 1-Mar-94 BobDay Created
  3305. //
  3306. // Notes: This thunk is 2nd part of a 2-byte thop.
  3307. //
  3308. //----------------------------------------------------------------------------
  3309. DWORD Thop_Enum_STATSTG_1632(THUNKINFO *pti)
  3310. {
  3311. return General_Enum_1632(pti,
  3312. sizeof(STATSTG),
  3313. sizeof(STATSTG),
  3314. Callback_STATSTG_1632,
  3315. Cleanup_STATSTG_1632 );
  3316. }
  3317. //+---------------------------------------------------------------------------
  3318. //
  3319. // Function: Callback_FORMATETC_1632, public
  3320. //
  3321. // Synopsis: Prepares the FORMATETC structure for the copy back into 16-bit
  3322. // address space.
  3323. //
  3324. // Arguments: [pti] - Thunking state information
  3325. // [lp32] - Pointer to 32-bit returned structure
  3326. // [lp16] - Pointer to 16-bit output structure
  3327. //
  3328. // Returns: SCODE indicating success/failure
  3329. //
  3330. // History: 1-Mar-94 BobDay Created
  3331. //
  3332. //----------------------------------------------------------------------------
  3333. SCODE Callback_FORMATETC_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3334. {
  3335. (FIXVDMPTR(vp16, FORMATETC16))->ptd = NULL;
  3336. RELVDMPTR(vp16);
  3337. return ConvertFetc3216(pti, (FORMATETC *)lp32, vp16, TRUE);
  3338. }
  3339. //+---------------------------------------------------------------------------
  3340. //
  3341. // Function: Cleanup_FORMATETC_1632, public
  3342. //
  3343. // Synopsis: Cleans up the any FORMATETCs returned (either to 16-bit
  3344. // or 32-bit)
  3345. //
  3346. // Arguments: [pti] - Thunking state information
  3347. // [lp32] - Pointer to 32-bit returned structure
  3348. // [lp16] - Pointer to 16-bit output structure
  3349. //
  3350. // Returns: nothing, should NEVER fail
  3351. //
  3352. // History: 1-Mar-94 BobDay Created
  3353. //
  3354. //----------------------------------------------------------------------------
  3355. void Cleanup_FORMATETC_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3356. {
  3357. FORMATETC16 UNALIGNED *lpformatetc16;
  3358. VPVOID vptd;
  3359. lpformatetc16 = FIXVDMPTR( vp16, FORMATETC16 );
  3360. vptd = lpformatetc16->ptd;
  3361. RELVDMPTR(vp16);
  3362. if (vptd != 0)
  3363. {
  3364. TaskFree16(vptd);
  3365. }
  3366. }
  3367. //+---------------------------------------------------------------------------
  3368. //
  3369. // Function: Thop_Enum_FORMATETC_1632, public
  3370. //
  3371. // Synopsis: Thunks IEnumFORMATETC::Next parameters
  3372. //
  3373. // Arguments: [pti] - Thunk state information
  3374. //
  3375. // Returns: Appropriate status code
  3376. //
  3377. // History: 1-Mar-94 BobDay Created
  3378. //
  3379. // Notes: This thunk is 2nd part of a 2-byte thop.
  3380. //
  3381. //----------------------------------------------------------------------------
  3382. DWORD Thop_Enum_FORMATETC_1632(THUNKINFO *pti)
  3383. {
  3384. return General_Enum_1632(pti,
  3385. sizeof(FORMATETC),
  3386. sizeof(FORMATETC16),
  3387. Callback_FORMATETC_1632,
  3388. Cleanup_FORMATETC_1632 );
  3389. }
  3390. //+---------------------------------------------------------------------------
  3391. //
  3392. // Function: Callback_STATDATA_1632, public
  3393. //
  3394. // Synopsis: Prepares the STATDATA structure for the copy back into 16-bit
  3395. // address space.
  3396. //
  3397. // Arguments: [pti] - Thunking state information
  3398. // [lp32] - Pointer to 32-bit returned structure
  3399. // [lp16] - Pointer to 16-bit output structure
  3400. //
  3401. // Returns: SCODE indicating success/failure
  3402. //
  3403. // History: 1-Mar-94 BobDay Created
  3404. //
  3405. //----------------------------------------------------------------------------
  3406. SCODE Callback_STATDATA_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3407. {
  3408. SCODE sc;
  3409. LPSTATDATA lpstatdata32;
  3410. STATDATA16 UNALIGNED *lpstatdata16;
  3411. VPVOID vpadv16;
  3412. sc = S_OK;
  3413. lpstatdata32 = (LPSTATDATA)lp32;
  3414. if (lpstatdata32->pAdvSink != NULL)
  3415. {
  3416. // We don't know whether it's an AdviseSink or
  3417. // an AdviseSink2, so pass AdviseSink2 since it's
  3418. // a superset of AdviseSink and will work for both
  3419. vpadv16 = pti->pThkMgr->FindProxy1632(NULL, lpstatdata32->pAdvSink, NULL,
  3420. INDEX_IIDIDX(THI_IAdviseSink2),
  3421. NULL);
  3422. // Release the actual 32-bit IAdviseSink as it is a OUT parameter
  3423. // This could be the last release on the interface if the
  3424. // above call failed;
  3425. lpstatdata32->pAdvSink->Release();
  3426. if(!vpadv16) {
  3427. sc = E_OUTOFMEMORY;
  3428. }
  3429. }
  3430. else
  3431. {
  3432. vpadv16 = 0;
  3433. }
  3434. lpstatdata16 = FIXVDMPTR( vp16, STATDATA16 );
  3435. lpstatdata16->formatetc.ptd = NULL;
  3436. if (SUCCEEDED(sc))
  3437. {
  3438. // If this fails the AdviseSink proxy will be cleaned up in
  3439. // the cleanup function later
  3440. sc = ConvertFetc3216(pti,
  3441. &lpstatdata32->formatetc,
  3442. vp16+FIELD_OFFSET(STATDATA16, formatetc), TRUE);
  3443. }
  3444. if (SUCCEEDED(sc))
  3445. {
  3446. lpstatdata16->advf = lpstatdata32->advf;
  3447. lpstatdata16->pAdvSink = vpadv16;
  3448. lpstatdata16->dwConnection = lpstatdata32->dwConnection;
  3449. }
  3450. RELVDMPTR(vp16);
  3451. return sc;
  3452. }
  3453. //+---------------------------------------------------------------------------
  3454. //
  3455. // Function: Cleanup_STATDATA_1632, public
  3456. //
  3457. // Synopsis: Cleans up the any STATDATAs returned (either to 16-bit
  3458. // or 32-bit)
  3459. //
  3460. // Arguments: [pti] - Thunking state information
  3461. // [lp32] - Pointer to 32-bit returned structure
  3462. // [lp16] - Pointer to 16-bit output structure
  3463. //
  3464. // Returns: nothing, should NEVER fail
  3465. //
  3466. // History: 1-Mar-94 BobDay Created
  3467. //
  3468. //----------------------------------------------------------------------------
  3469. void Cleanup_STATDATA_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3470. {
  3471. STATDATA *lpstatdata32;
  3472. STATDATA16 UNALIGNED *lpstatdata16;
  3473. LPADVISESINK lpadv32;
  3474. VPVOID vptd;
  3475. lpstatdata32 = (STATDATA FAR *)lp32;
  3476. lpadv32 = lpstatdata32->pAdvSink;
  3477. lpstatdata16 = FIXVDMPTR( vp16, STATDATA16 );
  3478. vptd = lpstatdata16->formatetc.ptd;
  3479. RELVDMPTR(vp16);
  3480. if(lpstatdata16->pAdvSink) {
  3481. // Release the proxy to 32-bit interface
  3482. pti->pThkMgr->ReleaseProxy1632((VPVOID) lpstatdata32->pAdvSink);
  3483. }
  3484. if (vptd != 0)
  3485. {
  3486. TaskFree16(vptd);
  3487. }
  3488. }
  3489. //+---------------------------------------------------------------------------
  3490. //
  3491. // Function: Thop_Enum_STATDATA_1632, public
  3492. //
  3493. // Synopsis: Thunks IEnumSTATDATA::Next parameters
  3494. //
  3495. // Arguments: [pti] - Thunk state information
  3496. //
  3497. // Returns: Appropriate status code
  3498. //
  3499. // History: 1-Mar-94 BobDay Created
  3500. //
  3501. // Notes: This thunk is 2nd part of a 2-byte thop.
  3502. //
  3503. //----------------------------------------------------------------------------
  3504. DWORD Thop_Enum_STATDATA_1632(THUNKINFO *pti)
  3505. {
  3506. return General_Enum_1632(pti,
  3507. sizeof(STATDATA),
  3508. sizeof(STATDATA16),
  3509. Callback_STATDATA_1632,
  3510. Cleanup_STATDATA_1632 );
  3511. }
  3512. //+---------------------------------------------------------------------------
  3513. //
  3514. // Function: Callback_MONIKER_1632, public
  3515. //
  3516. // Synopsis: Prepares the MONIKER structure for the copy back into 16-bit
  3517. // address space.
  3518. //
  3519. // Arguments: [pti] - Thunking state information
  3520. // [lp32] - Pointer to 32-bit returned structure
  3521. // [lp16] - Pointer to 16-bit output structure
  3522. //
  3523. // Returns: SCODE indicating success/failure
  3524. //
  3525. // History: 1-Mar-94 BobDay Created
  3526. //
  3527. //----------------------------------------------------------------------------
  3528. SCODE Callback_MONIKER_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3529. {
  3530. VPVOID vpmoniker16;
  3531. SCODE sc = S_OK;
  3532. vpmoniker16 = pti->pThkMgr->FindProxy1632(NULL, *(LPMONIKER *)lp32, NULL,
  3533. INDEX_IIDIDX(THI_IMoniker),
  3534. NULL);
  3535. // Release the actual 32-bit IMoniker as it is a OUT parameter
  3536. // This could be the last release on the interface if the
  3537. // above call failed;
  3538. (*(LPMONIKER *)lp32)->Release();
  3539. if(!vpmoniker16) {
  3540. sc = E_OUTOFMEMORY;
  3541. }
  3542. *FIXVDMPTR(vp16, VPVOID) = vpmoniker16;
  3543. RELVDMPTR(vp16);
  3544. return sc;
  3545. }
  3546. //+---------------------------------------------------------------------------
  3547. //
  3548. // Function: Cleanup_MONIKER_1632, public
  3549. //
  3550. // Synopsis: Cleans up the any MONIKERs returned (either to 16-bit
  3551. // or 32-bit)
  3552. //
  3553. // Arguments: [pti] - Thunking state information
  3554. // [lp32] - Pointer to 32-bit returned structure
  3555. // [lp16] - Pointer to 16-bit output structure
  3556. //
  3557. // Returns: nothing, should NEVER fail
  3558. //
  3559. // History: 1-Mar-94 BobDay Created
  3560. //
  3561. //----------------------------------------------------------------------------
  3562. void Cleanup_MONIKER_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3563. {
  3564. LPMONIKER lpmoniker32;
  3565. VPVOID vpmoniker16;
  3566. vpmoniker16 = *FIXVDMPTR( vp16, VPVOID );
  3567. RELVDMPTR(vp16);
  3568. lpmoniker32 = *(LPMONIKER *)lp32;
  3569. if(vpmoniker16) {
  3570. pti->pThkMgr->ReleaseProxy1632(vpmoniker16);
  3571. }
  3572. }
  3573. //+---------------------------------------------------------------------------
  3574. //
  3575. // Function: Thop_Enum_MONIKER_1632, public
  3576. //
  3577. // Synopsis: Thunks IEnumMONIKER::Next parameters
  3578. //
  3579. // Arguments: [pti] - Thunk state information
  3580. //
  3581. // Returns: Appropriate status code
  3582. //
  3583. // History: 1-Mar-94 BobDay Created
  3584. //
  3585. // Notes: This thunk is 2nd part of a 2-byte thop.
  3586. //
  3587. //----------------------------------------------------------------------------
  3588. DWORD Thop_Enum_MONIKER_1632(THUNKINFO *pti)
  3589. {
  3590. return General_Enum_1632(pti,
  3591. sizeof(LPMONIKER),
  3592. sizeof(LPMONIKER),
  3593. Callback_MONIKER_1632,
  3594. Cleanup_MONIKER_1632 );
  3595. }
  3596. //+---------------------------------------------------------------------------
  3597. //
  3598. // Function: Callback_OLEVERB_1632, public
  3599. //
  3600. // Synopsis: Prepares the OLEVERB structure for the copy back into 16-bit
  3601. // address space.
  3602. //
  3603. // Arguments: [pti] - Thunking state information
  3604. // [lp32] - Pointer to 32-bit returned structure
  3605. // [lp16] - Pointer to 16-bit output structure
  3606. //
  3607. // Returns: SCODE indicating success/failure
  3608. //
  3609. // History: 1-Mar-94 BobDay Created
  3610. //
  3611. //----------------------------------------------------------------------------
  3612. SCODE Callback_OLEVERB_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3613. {
  3614. SCODE sc;
  3615. OLEVERB *lpoleverb32;
  3616. OLEVERB UNALIGNED *lpoleverb16;
  3617. VPSTR vpstr;
  3618. lpoleverb32 = (LPOLEVERB)lp32;
  3619. vpstr = 0;
  3620. sc = ConvertTaskString3216(pti, lpoleverb32->lpszVerbName, NULL, 0,
  3621. &vpstr);
  3622. lpoleverb16 = FIXVDMPTR(vp16, OLEVERB);
  3623. lpoleverb16->lpszVerbName = (LPOLESTR)vpstr;
  3624. if (SUCCEEDED(sc))
  3625. {
  3626. lpoleverb16->lVerb = lpoleverb32->lVerb;
  3627. lpoleverb16->fuFlags = lpoleverb32->fuFlags;
  3628. lpoleverb16->grfAttribs = lpoleverb32->grfAttribs;
  3629. }
  3630. RELVDMPTR(vp16);
  3631. return sc;
  3632. }
  3633. //+---------------------------------------------------------------------------
  3634. //
  3635. // Function: Cleanup_OLEVERB_1632, public
  3636. //
  3637. // Synopsis: Cleans up the any OLEVERBs returned (either to 16-bit
  3638. // or 32-bit)
  3639. //
  3640. // Arguments: [pti] - Thunking state information
  3641. // [lp32] - Pointer to 32-bit returned structure
  3642. // [lp16] - Pointer to 16-bit output structure
  3643. //
  3644. // Returns: nothing, should NEVER fail
  3645. //
  3646. // History: 1-Mar-94 BobDay Created
  3647. //
  3648. //----------------------------------------------------------------------------
  3649. void Cleanup_OLEVERB_1632( THUNKINFO *pti, LPVOID lp32, VPVOID vp16 )
  3650. {
  3651. OLEVERB UNALIGNED *lpoleverb16;
  3652. VPVOID vpstr;
  3653. lpoleverb16 = FIXVDMPTR( vp16, OLEVERB );
  3654. vpstr = (VPVOID)lpoleverb16->lpszVerbName;
  3655. RELVDMPTR(vp16);
  3656. if ( vpstr != 0 )
  3657. {
  3658. TaskFree16( vpstr );
  3659. }
  3660. }
  3661. //+---------------------------------------------------------------------------
  3662. //
  3663. // Function: Thop_Enum_OLEVERB_1632, public
  3664. //
  3665. // Synopsis: Thunks IEnumOLEVERB::Next parameters
  3666. //
  3667. // Arguments: [pti] - Thunk state information
  3668. //
  3669. // Returns: Appropriate status code
  3670. //
  3671. // History: 1-Mar-94 BobDay Created
  3672. //
  3673. // Notes: This thunk is 2nd part of a 2-byte thop.
  3674. //
  3675. //----------------------------------------------------------------------------
  3676. DWORD Thop_Enum_OLEVERB_1632(THUNKINFO *pti)
  3677. {
  3678. return General_Enum_1632(pti,
  3679. sizeof(OLEVERB),
  3680. sizeof(OLEVERB),
  3681. Callback_OLEVERB_1632,
  3682. Cleanup_OLEVERB_1632 );
  3683. }
  3684. #define THOP_EFN(x) Thop_Enum_ ## x ## _1632
  3685. DWORD (*CONST aThopEnumFunctions1632[])(THUNKINFO *) =
  3686. {
  3687. THOP_EFN(STRING), // STRING
  3688. THOP_EFN(UNKNOWN), // UNKNOWN
  3689. THOP_EFN(STATSTG), // STATSTG
  3690. THOP_EFN(FORMATETC), // FORMATETC
  3691. THOP_EFN(STATDATA), // STATDATA
  3692. THOP_EFN(MONIKER), // MONIKER
  3693. THOP_EFN(OLEVERB), // OLEVERB
  3694. };