Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
6.4 KiB

  1. /*
  2. * genthunk - Generic thunks
  3. */
  4. #ifndef WIN32
  5. #include "tweakui.h"
  6. const char CODESEG szKernel32[] = "KERNEL32";
  7. /*****************************************************************************
  8. *
  9. * hwnd32Hwnd converts a 16-bit hwnd to a 32-bit hwnd. Note that we
  10. * extend with 0xFFFF to be compatible with NT.
  11. *
  12. *****************************************************************************/
  13. #define hwnd32Hwnd(hwnd) MAKELONG(hwnd, 0xFFFF)
  14. /*****************************************************************************
  15. *
  16. * CallProcEx32W (a.k.a. ThunkMeHarder)
  17. *
  18. * Generic wrapper for thunking.
  19. *
  20. * lpszDll -> ASCIIZ DLL name
  21. * lpszProc -> ASCIIZ procedure name
  22. * c = number of arguments
  23. * dwMask = bitmask; if argument N is a pointer, then bit c-N is set.
  24. * Yes, it's backwards.
  25. * arg0, arg1, arg2, ... = arguments
  26. *
  27. * Returns whatever the procedure returns, or 0 on error.
  28. *
  29. * To aid in building dwMask, the macro ARGPTR(k,n) builds the
  30. * appropriate bitmask that indicates that argument k of n is
  31. * a pointer. k is zero-based, of course.
  32. *
  33. * This is pretty gross evil code that is Intel x86-specific.
  34. * But hey, it's Win16. That's to be expected.
  35. *
  36. * CallProc32W is insane. It's a variadic function that uses
  37. * the pascal calling convention. (It probably makes more sense
  38. * when you're stoned.)
  39. *
  40. *****************************************************************************/
  41. DWORD PASCAL GetProcAddressEx32W(DWORD hinst, LPCSTR lpsz);
  42. DWORD WINAPI LoadLibraryEx32W(LPCSTR lpszLib, DWORD dw1, DWORD dw2);
  43. DWORD WINAPI GetProcAddress32W(DWORD hinst, LPCSTR lpsz);
  44. DWORD WINAPI FreeLibrary32W(DWORD hinst);
  45. DWORD WINAPI CallProc32W(DWORD pfn, DWORD dwMask, DWORD c);
  46. #define CallProcEx32W ThunkMeHarder
  47. #define ARGPTR(k,n) (1<<(n-k-1))
  48. DWORD _cdecl
  49. ThunkMeHarder(LPCSTR lpszDll, LPCSTR lpszProc, UINT c, DWORD dwMask, ...)
  50. {
  51. DWORD dwRc = 0;
  52. DWORD hdll, pfn;
  53. if (SELECTOROF(lpszDll) ?
  54. (HIWORD(hdll = LoadLibraryEx32W(lpszDll, 0, 0)) &&
  55. HIWORD(pfn = GetProcAddressEx32W(hdll, lpszProc)))
  56. : (hdll = 0, pfn = (DWORD)lpszProc, 1)) {
  57. _asm {
  58. mov cx, c /* cx = number of arguments */
  59. xor si, si /* si = number of bytes pushed */
  60. jcxz PushesDone
  61. PushHarder:
  62. _emit 0x66 /* 32-bit override */
  63. push word ptr dwMask[4+si]
  64. add si, 4
  65. loop PushHarder
  66. PushesDone:
  67. }
  68. dwRc = CallProc32W(pfn, dwMask, c);
  69. }
  70. if (HIWORD(hdll)) FreeLibrary32W(hdll);
  71. return dwRc;
  72. }
  73. /*****************************************************************************
  74. *
  75. * GetProcAddressEx32W
  76. *
  77. * The same as GetProcAddress32W, except it also understands ordinals.
  78. *
  79. * Yes, this is a rather close relationship we have with ThunkMeHarder,
  80. *
  81. *
  82. * (The Shell VxD does a very similar thing)
  83. *
  84. *****************************************************************************/
  85. const char CODESEG szGetProcAddress[] = "GetProcAddress";
  86. DWORD PASCAL
  87. GetProcAddressEx32W(DWORD hinst, LPCSTR lpsz)
  88. {
  89. if (SELECTOROF(lpsz)) { /* Optimization */
  90. return GetProcAddress32W(hinst, lpsz);
  91. } else {
  92. return ThunkMeHarder(szKernel32, szGetProcAddress, 2, 0, hinst, lpsz);
  93. }
  94. }
  95. /*****************************************************************************
  96. *
  97. * CopyFile
  98. *
  99. *****************************************************************************/
  100. const char CODESEG szCopyFileA[] = "CopyFileA";
  101. BOOL PASCAL
  102. CopyFile(LPCSTR lpszSrc, LPCSTR lpszDst, BOOL fFailExists)
  103. {
  104. return CallProcEx32W(szKernel32, szCopyFileA, 3, ARGPTR(0,3)|ARGPTR(1,3),
  105. lpszSrc, lpszDst, (DWORD)fFailExists) != 0;
  106. }
  107. /*****************************************************************************
  108. *
  109. * SHChangeNotify
  110. *
  111. * Actually, we are slimy because we *know* that uFlags is always
  112. * SHCNF_PIDL, so no parameters need to be thunked.
  113. *
  114. *****************************************************************************/
  115. const char CODESEG szSHChangeNotify[] = "SHChangeNotify";
  116. void PASCAL SHChangeNotify(LONG wEventId, UINT uFlags,
  117. const void FAR *dwItem1, const void FAR *dwItem2)
  118. {
  119. CallProcEx32W(szShell32, szSHChangeNotify, 4, 0,
  120. wEventId, (DWORD)uFlags, dwItem1, dwItem2);
  121. }
  122. /*****************************************************************************
  123. *
  124. * SHGetSpecialFolderLocation
  125. *
  126. * Ignore the return value; just check the pidl.
  127. *
  128. *****************************************************************************/
  129. const char CODESEG szSHGetSpecialFolderLocation[]
  130. = "SHGetSpecialFolderLocation";
  131. void PASCAL
  132. SHGetSpecialFolderLocation(HWND hwnd, int nFolder, PIDL FAR *ppidl)
  133. {
  134. CallProcEx32W(szShell32, szSHGetSpecialFolderLocation, 3, ARGPTR(2,3),
  135. hwnd32Hwnd(hwnd), (LONG)nFolder, (LPVOID)ppidl);
  136. }
  137. /*****************************************************************************
  138. *
  139. * SHGetPathFromIDList
  140. *
  141. * Ignore the return value; just check the pidl.
  142. *
  143. *****************************************************************************/
  144. const char CODESEG szSHGetPathFromIDList[] = "SHGetPathFromIDList";
  145. void PASCAL
  146. SHGetPathFromIDList(PIDL pidl, LPSTR pszBuf)
  147. {
  148. CallProcEx32W(szShell32, szSHGetPathFromIDList, 2, ARGPTR(1,2),
  149. pidl, pszBuf);
  150. }
  151. /*****************************************************************************
  152. *
  153. * ILFree
  154. *
  155. * This is exported by ordinal.
  156. *
  157. *****************************************************************************/
  158. void WINAPI
  159. ILFree(PIDL pidl)
  160. {
  161. CallProcEx32W(szShell32, MAKEINTRESOURCE(155), 1, 0, pidl);
  162. }
  163. /*****************************************************************************
  164. *
  165. * Shell_GetImageLists
  166. *
  167. * This is exported by ordinal.
  168. *
  169. *****************************************************************************/
  170. BOOL PASCAL
  171. Shell_GetImageLists(HIMAGELIST FAR *phiml, HIMAGELIST FAR *phimlSmall)
  172. {
  173. return (BOOL)CallProcEx32W(szShell32, MAKEINTRESOURCE(71), 2,
  174. ARGPTR(0,2)|ARGPTR(1,2), phiml, phimlSmall);
  175. }
  176. /*****************************************************************************
  177. *
  178. * ExtractIconEx
  179. *
  180. *****************************************************************************/
  181. const char CODESEG szExtractIconExA[] = "ExtractIconExA";
  182. int PASCAL
  183. ExtractIconEx(LPCSTR pszFile, int iIcon,
  184. HICON FAR *phiconLarge, HICON FAR *phiconSmall, int nIcons)
  185. {
  186. return (int)CallProcEx32W(szShell32, szExtractIconExA, 5,
  187. ARGPTR(0,5)|ARGPTR(2,5)|ARGPTR(3,5),
  188. pszFile, (LONG)iIcon, phiconLarge, phiconSmall,
  189. (LONG)nIcons);
  190. }
  191. #endif /* !WIN32 */