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.

253 lines
6.5 KiB

  1. /*++
  2. * intthunk.c
  3. *
  4. * WOW v5.0
  5. *
  6. * Copyright 1996, Microsoft Corporation. All Rights Reserved.
  7. *
  8. * WOW32.C
  9. * WOW32 16-bit API support
  10. *
  11. * History:
  12. * Created 7-Dec-96 DaveHart
  13. *
  14. --*/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #include "wowit.h" // this is generated by genthunk.exe and is placed in
  18. // .\daytona\obj\i386 along with wowit.c
  19. MODNAME(intthunk.c);
  20. extern DWORD WK32ICallProc32MakeCall(DWORD pfn, DWORD cbArgs, VOID *pArgs);
  21. //
  22. // On x86 we don't bother aligning pointers to DWORDs
  23. // passed to APIs. Perhaps we shouldn't for Alpha?
  24. //
  25. #ifdef _X86_
  26. #define ALIGNDWORDS 0
  27. #else
  28. #define ALIGNDWORDS 1
  29. #endif
  30. ULONG FASTCALL InterpretThunk(PVDMFRAME pFrame, DWORD dwIntThunkID)
  31. {
  32. PINT_THUNK_TABLEENTRY pit = &IntThunkTable[ dwIntThunkID ];
  33. CONST BYTE * pbInstr = pit->pbInstr;
  34. DWORD dwArgs32[MAX_IT_ARGS];
  35. PDWORD pdwArg32 = dwArgs32;
  36. #if ALIGNDWORDS
  37. BOOL fAlignedUsed = FALSE;
  38. DWORD adwAligned[MAX_IT_ARGS];
  39. PDWORD pdwAligned = adwAligned;
  40. DWORD avpAligned[MAX_IT_ARGS];
  41. PDWORD pvpAligned = avpAligned;
  42. #endif
  43. WORD UNALIGNED *pwArg16 = (WORD UNALIGNED *) ((PBYTE)&pFrame->bArgs + pFrame->cbArgs - 2);
  44. DWORD dwReturn;
  45. DWORD dw;
  46. WOW32ASSERTMSGF(dwIntThunkID <= ITID_MAX,
  47. ("WOW32 InterpretThunk error ID %d out of range (%d max).\n",
  48. dwIntThunkID, ITID_MAX));
  49. while ( ! (*pbInstr & IT_RETMASK)) {
  50. switch (*pbInstr) {
  51. case IT_WORD:
  52. *pdwArg32 = *pwArg16;
  53. break;
  54. case IT_INT:
  55. *pdwArg32 = INT32(*pwArg16);
  56. break;
  57. case IT_DWORD:
  58. *pdwArg32 = *(DWORD UNALIGNED *) --pwArg16;
  59. break;
  60. case IT_LPDWORD:
  61. #if ALIGNDWORDS
  62. if (! fAlignedUsed) {
  63. fAlignedUsed = TRUE;
  64. RtlZeroMemory(avpAligned, sizeof avpAligned);
  65. }
  66. *pvpAligned = *(DWORD UNALIGNED *) --pwArg16;
  67. if (*pvpAligned) {
  68. *pdwArg32 = (DWORD) pdwAligned;
  69. *pdwAligned = *(DWORD UNALIGNED *) GetPModeVDMPointer(*pvpAligned, 4);
  70. } else {
  71. *pdwArg32 = 0;
  72. }
  73. break;
  74. #else
  75. //
  76. // If we aren't aligning DWORDs use the generic
  77. // pointer code.
  78. //
  79. /* FALL THROUGH TO IT_PTR */
  80. #endif
  81. case IT_PTR:
  82. dw = *(DWORD UNALIGNED *) --pwArg16;
  83. do_IT_PTR_with_dw:
  84. *pdwArg32 = (DWORD) GetPModeVDMPointer(dw, 0);
  85. break;
  86. case IT_PTRORATOM:
  87. dw = *(DWORD UNALIGNED *) --pwArg16;
  88. if (HIWORD(dw)) {
  89. goto do_IT_PTR_with_dw;
  90. }
  91. *pdwArg32 = dw; // atom
  92. break;
  93. case IT_HGDI:
  94. *pdwArg32 = (DWORD) GDI32( (HAND16) *pwArg16 );
  95. break;
  96. case IT_HUSER:
  97. *pdwArg32 = (DWORD) USER32( (HAND16) *pwArg16 );
  98. break;
  99. case IT_COLOR:
  100. dw = *(DWORD UNALIGNED *) --pwArg16;
  101. *pdwArg32 = COLOR32(dw);
  102. break;
  103. case IT_HINST:
  104. *pdwArg32 = (DWORD) HINSTRES32( (HAND16) *pwArg16 );
  105. break;
  106. case IT_HICON:
  107. *pdwArg32 = (DWORD) HICON32( (HAND16) *pwArg16 );
  108. break;
  109. case IT_HCURS:
  110. *pdwArg32 = (DWORD) HCURSOR32( (HAND16) *pwArg16 );
  111. break;
  112. case IT_16ONLY:
  113. //
  114. // This is for params that appear on 16-bit side but not 32-bit side,
  115. // for example the hinstOwner passed to CopyImage in Win16 but not in Win32.
  116. //
  117. pdwArg32--;
  118. break;
  119. case IT_32ONLY:
  120. //
  121. // This is for params that appear on 32-bit side but not 16-bit side,
  122. // we pass zero for the 32-bit argument.
  123. //
  124. *pdwArg32 = 0;
  125. pwArg16++;
  126. break;
  127. default:
  128. WOW32ASSERTMSGF(FALSE, ("WOW32 InterpretThunk error unknown opcode 0x%x.\n", *pbInstr));
  129. }
  130. pwArg16--;
  131. pdwArg32++;
  132. pbInstr++;
  133. #if ALIGNDWORDS
  134. pdwAligned++;
  135. pvpAligned++;
  136. #endif
  137. WOW32ASSERT((pbInstr - pit->pbInstr) <= (MAX_IT_ARGS + 1));
  138. }
  139. //
  140. // Call API
  141. //
  142. dwReturn = WK32ICallProc32MakeCall(
  143. (DWORD) pit->pfnAPI,
  144. (PBYTE) pdwArg32 - (PBYTE) dwArgs32,
  145. dwArgs32
  146. );
  147. #ifdef DEBUG
  148. pFrame = NULL; // Memory movement may have occurred.
  149. #endif
  150. //
  151. // If we passed aligned DWORD pointers, copy the values back.
  152. //
  153. #if ALIGNDWORDS
  154. if (fAlignedUsed) {
  155. pdwAligned = adwAligned;
  156. pvpAligned = avpAligned;
  157. while (pvpAligned < (PDWORD)((PBYTE)avpAligned + sizeof avpAligned)) {
  158. if (*pvpAligned) {
  159. *(DWORD UNALIGNED *) GetPModeVDMPointer(*pvpAligned, 4) = *pdwAligned;
  160. }
  161. pdwAligned++;
  162. pvpAligned++;
  163. }
  164. }
  165. #endif
  166. //
  167. // Thunk return value using last instruction opcode
  168. //
  169. WOW32ASSERT(*pbInstr & IT_RETMASK);
  170. switch (*pbInstr) {
  171. case IT_DWORDRET:
  172. // dwReturn is correct
  173. break;
  174. case IT_WORDRET:
  175. dwReturn = GETWORD16(dwReturn);
  176. break;
  177. case IT_INTRET:
  178. dwReturn = (DWORD) GETINT16(dwReturn);
  179. break;
  180. case IT_HGDIRET:
  181. dwReturn = GDI16( (HAND32) dwReturn );
  182. break;
  183. case IT_HUSERRET:
  184. dwReturn = USER16( (HAND32) dwReturn );
  185. break;
  186. case IT_ZERORET:
  187. dwReturn = 0;
  188. break;
  189. case IT_HICONRET:
  190. dwReturn = GETHICON16( (HAND32) dwReturn );
  191. break;
  192. case IT_HCURSRET:
  193. dwReturn = GETHCURSOR16( (HAND32) dwReturn );
  194. break;
  195. case IT_ONERET:
  196. dwReturn = 1;
  197. break;
  198. case IT_HPRNDWPRET:
  199. dwReturn = GetPrn16( (HAND32) dwReturn );
  200. break;
  201. default:
  202. WOW32ASSERTMSGF(FALSE, ("WOW32 InterpretThunk error unknown return opcode 0x%x.\n", *pbInstr));
  203. }
  204. return dwReturn;
  205. }