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.

406 lines
12 KiB

  1. /****************************************************************************
  2. thunks.c
  3. Contains code for thunking msvideo.dll from 16bit to 32bit
  4. Copyright (c) Microsoft Corporation 1994. All rights reserved
  5. Basic Structure:
  6. When loaded, the 16 bit DLL will try to find the corresponding
  7. 32 bit DLL. There are two of these.
  8. The 32bit videoXXXX api entry points are in AVICAP32.DLL
  9. The 32bit ICM code is in MSVFW32.DLL
  10. The thunk initialisation routine will check the code is running on
  11. Windows NT. If not, no further initialisation is done. This
  12. ensures that the same binary can be used on NT, and other Windows
  13. platforms.
  14. The code then attempts to access the special entry points provided
  15. in KERNEL.DLL for loading and calling 32 bit entry points. If this
  16. link fails, no thunking can be done.
  17. Each of the 32 bit DLLs is loaded in turn, and GetProcAddress32 is
  18. called for the special thunk entry point. If all works then two
  19. global flags are set (independently of each other).
  20. gfVideo32 == TRUE means that the videoXXXX apis can be called.
  21. gfICM32 == TRUE means that the 32 bit ICM code is available.
  22. ****************************************************************************/
  23. #include <windows.h>
  24. #define MMNOMCI
  25. #include <win32.h>
  26. #include <mmsystem.h>
  27. #include <msvideo.h>
  28. #include <msviddrv.h>
  29. #include <compman.h>
  30. #include "vidthunk.h"
  31. #include "msvideoi.h"
  32. SZCODE gszKernel[] = TEXT("KERNEL");
  33. SZCODE gszLoadLibraryEx32W[] = TEXT("LoadLibraryEx32W");
  34. //SZCODE gszFreeLibraryEx32W[] = TEXT("FreeLibraryEx32W");
  35. SZCODE gszFreeLibrary32W[] = TEXT("FreeLibrary32W");
  36. SZCODE gszGetProcAddress32W[] = TEXT("GetProcAddress32W");
  37. SZCODE gszCallproc32W[] = TEXT("CallProc32W");
  38. SZCODE gszVideoThunkEntry[] = TEXT("videoThunk32");
  39. SZCODE gszVideo32[] = TEXT("avicap32.dll");
  40. SZCODE gszICMThunkEntry[] = TEXT("ICMThunk32");
  41. SZCODE gszICMThunkEntry2[] = TEXT("ICMTHUNK32");
  42. SZCODE gszICM32[] = TEXT("msvfw32.dll");
  43. VIDTHUNK pvth;
  44. #ifndef WIN32
  45. //--------------------------------------------------------------------------;
  46. //
  47. // BOOL InitThunks
  48. //
  49. // Description:
  50. //
  51. //
  52. // Arguments:
  53. // None.
  54. //
  55. // Return (BOOL):
  56. //
  57. // History:
  58. //
  59. //
  60. //--------------------------------------------------------------------------;
  61. void FAR PASCAL InitThunks(VOID)
  62. {
  63. HMODULE hmodKernel;
  64. DWORD (FAR PASCAL *lpfnLoadLibraryEx32W)(LPCSTR, DWORD, DWORD);
  65. LPVOID (FAR PASCAL *lpfnGetProcAddress32W)(DWORD, LPCSTR);
  66. DWORD (FAR PASCAL *lpfnFreeLibrary32W)(DWORD hLibModule);
  67. //
  68. // Check if we're WOW
  69. //
  70. // if (!(GetWinFlags() & WF_WINNT)) {
  71. // //DPF(("Not running in WOW... returning FALSE\n"));
  72. // return;
  73. // }
  74. //
  75. // See if we can find the thunking routine entry points in KERNEL
  76. //
  77. hmodKernel = GetModuleHandle(gszKernel);
  78. if (hmodKernel == NULL)
  79. {
  80. DPF(("Cannot link to kernel module... returning FALSE\n"));
  81. return; // !!!!
  82. }
  83. *(FARPROC *)&lpfnLoadLibraryEx32W =
  84. GetProcAddress(hmodKernel, gszLoadLibraryEx32W);
  85. if (lpfnLoadLibraryEx32W == NULL)
  86. {
  87. DPF(("Cannot get address of LoadLibrary32... returning FALSE\n"));
  88. return;
  89. }
  90. *(FARPROC *)&lpfnGetProcAddress32W =
  91. GetProcAddress(hmodKernel, gszGetProcAddress32W);
  92. if (lpfnGetProcAddress32W == NULL)
  93. {
  94. DPF(("Cannot get address of GetProcAddress32... returning FALSE\n"));
  95. return;
  96. }
  97. *(FARPROC *)&pvth.lpfnCallproc32W =
  98. GetProcAddress(hmodKernel, gszCallproc32W);
  99. if (pvth.lpfnCallproc32W == NULL)
  100. {
  101. DPF(("Cannot get address of CallProc32... returning FALSE\n"));
  102. return;
  103. }
  104. // In case we need to unload our 32 bit libraries...
  105. *(FARPROC *)&lpfnFreeLibrary32W =
  106. GetProcAddress(hmodKernel, gszFreeLibrary32W);
  107. //
  108. // See if we can get pointers to our thunking entry points
  109. //
  110. pvth.dwVideo32Handle = (*lpfnLoadLibraryEx32W)(gszVideo32, 0L, 0L);
  111. if (pvth.dwVideo32Handle != 0)
  112. {
  113. pvth.lpVideoThunkEntry = (*lpfnGetProcAddress32W)(pvth.dwVideo32Handle, gszVideoThunkEntry);
  114. if (pvth.lpVideoThunkEntry != NULL)
  115. {
  116. gfVideo32 = TRUE;
  117. } else {
  118. DPF(("Cannot get address of video thunk entry...\n"));
  119. if (lpfnFreeLibrary32W)
  120. {
  121. (*lpfnFreeLibrary32W)(pvth.dwVideo32Handle);
  122. }
  123. }
  124. } else {
  125. DPF(("Cannot load Video32 DLL...\n"));
  126. }
  127. pvth.dwICM32Handle = (*lpfnLoadLibraryEx32W)(gszICM32, 0L, 0L);
  128. if (pvth.dwICM32Handle != 0)
  129. {
  130. pvth.lpICMThunkEntry = (*lpfnGetProcAddress32W)(pvth.dwICM32Handle, gszICMThunkEntry);
  131. if (pvth.lpICMThunkEntry != NULL)
  132. {
  133. DPF(("ICM thunks OK!!\n"));
  134. gfICM32 = TRUE;
  135. } else {
  136. DPF(("Cannot get address of ICM thunk entry... trying #2\n"));
  137. pvth.lpICMThunkEntry = (*lpfnGetProcAddress32W)(pvth.dwICM32Handle, gszICMThunkEntry2);
  138. if (pvth.lpICMThunkEntry != NULL)
  139. {
  140. DPF(("ICM thunks OK!! (at second time of trying)\n"));
  141. gfICM32 = TRUE;
  142. } else {
  143. DPF(("Cannot get address of ICM thunk entry2...\n"));
  144. if (lpfnFreeLibrary32W)
  145. {
  146. (*lpfnFreeLibrary32W)(pvth.dwICM32Handle);
  147. }
  148. }
  149. }
  150. } else {
  151. DPF(("Cannot load ICM32 DLL...\n"));
  152. }
  153. return;
  154. }
  155. #endif // !WIN32
  156. //
  157. // The following functions generate calls to the 32-bit side
  158. //
  159. DWORD FAR PASCAL videoMessage32(HVIDEO hVideo, UINT msg, DWORD dwP1, DWORD dwP2)
  160. {
  161. /*
  162. * Check there's something on the other side!
  163. */
  164. if (!gfVideo32) {
  165. DPF(("videoMessage32 - no video thunks... returning FALSE\n"));
  166. return DV_ERR_INVALHANDLE;
  167. }
  168. /*
  169. * Watch out for hvideos being passed
  170. */
  171. if (msg == DVM_STREAM_INIT) {
  172. ((LPVIDEO_STREAM_INIT_PARMS)dwP1)->hVideo = hVideo;
  173. }
  174. return((DWORD)(pvth.lpfnCallproc32W)(vidThunkvideoMessage32,
  175. (DWORD)hVideo,
  176. (DWORD)msg,
  177. (DWORD)dwP1,
  178. (DWORD)dwP2,
  179. pvth.lpVideoThunkEntry,
  180. 0L, // no mapping of pointers
  181. 5L));
  182. }
  183. DWORD FAR PASCAL videoGetNumDevs32(void)
  184. {
  185. if (!gfVideo32) {
  186. DPF(("videoGetNumDevs32 - no video thunks... returning FALSE\n"));
  187. return 0;
  188. }
  189. return((DWORD)(pvth.lpfnCallproc32W)(vidThunkvideoGetNumDevs32,
  190. (DWORD)0,
  191. (DWORD)0,
  192. (DWORD)0,
  193. (DWORD)0,
  194. pvth.lpVideoThunkEntry,
  195. 0L, // no mapping of pointers
  196. 5L));
  197. }
  198. DWORD FAR PASCAL videoClose32(HVIDEO hVideo)
  199. {
  200. /*
  201. * Check there's something on the other side!
  202. */
  203. if (!gfVideo32) {
  204. DPF(("videoClose32 - no video thunks... returning FALSE\n"));
  205. return DV_ERR_INVALHANDLE;
  206. }
  207. return((DWORD)(pvth.lpfnCallproc32W)(vidThunkvideoClose32,
  208. (DWORD)hVideo,
  209. (DWORD)0,
  210. (DWORD)0,
  211. (DWORD)0,
  212. pvth.lpVideoThunkEntry,
  213. 0L, // no mapping of pointers
  214. 5L));
  215. }
  216. DWORD FAR PASCAL videoOpen32(LPHVIDEO lphVideo, DWORD dwDeviceID, DWORD dwFlags)
  217. {
  218. DWORD dwRetc;
  219. if (!gfVideo32) {
  220. DPF(("videoOpen32 - no video thunks... returning FALSE\n"));
  221. return DV_ERR_NOTDETECTED;
  222. }
  223. dwRetc = ((DWORD)(pvth.lpfnCallproc32W)(vidThunkvideoOpen32,
  224. (DWORD)lphVideo,
  225. (DWORD)dwDeviceID,
  226. (DWORD)dwFlags,
  227. (DWORD)0,
  228. pvth.lpVideoThunkEntry,
  229. 0L, // no mapping of pointers
  230. 5L));
  231. if (dwRetc == DV_ERR_OK) {
  232. #ifdef DEBUG
  233. if (Is32bitHandle(*lphVideo)) {
  234. //OutputDebugString("\nMSVIDEO : 32-bit handle does not fit in 16 bits!");
  235. DebugBreak();
  236. }
  237. #endif
  238. *lphVideo = Make32bitHandle(*lphVideo);
  239. }
  240. return dwRetc;
  241. }
  242. DWORD FAR PASCAL videoGetDriverDesc32(DWORD wDriverIndex,
  243. LPSTR lpszName, short cbName,
  244. LPSTR lpszVer, short cbVer)
  245. {
  246. if (!gfVideo32) {
  247. DPF(("videoGetDriverDesc32 - no video thunks... returning FALSE\n"));
  248. return DV_ERR_NOTDETECTED;
  249. }
  250. return (BOOL)(pvth.lpfnCallproc32W)(vidThunkvideoGetDriverDesc32,
  251. (DWORD)wDriverIndex,
  252. (DWORD)lpszName,
  253. (DWORD)lpszVer,
  254. (DWORD) MAKELONG(cbName, cbVer),
  255. pvth.lpVideoThunkEntry,
  256. 0L, // no mapping of pointers
  257. 5L); // 5 params
  258. }
  259. /*
  260. * The ICM thunking uses the same mechanism as for Video, but calls to a
  261. * different 32 bit DLL.
  262. */
  263. BOOL FAR PASCAL ICInfo32(DWORD fccType, DWORD fccHandler, ICINFO FAR * lpicInfo)
  264. {
  265. if (!gfICM32) {
  266. //OutputDebugString("ICInfo32: gfICM32 is not set - returning FALSE\n");
  267. return FALSE;
  268. }
  269. return ((BOOL)(pvth.lpfnCallproc32W)(compThunkICInfo32,
  270. (DWORD)fccType,
  271. (DWORD)fccHandler,
  272. (DWORD)lpicInfo,
  273. (DWORD)0,
  274. pvth.lpICMThunkEntry,
  275. 0L, // no mapping of pointers
  276. 5L));
  277. }
  278. LRESULT FAR PASCAL ICSendMessage32(DWORD hic, UINT msg, DWORD dwP1, DWORD dwP2)
  279. {
  280. /*
  281. * Check there's something on the other side!
  282. */
  283. if (!gfICM32) {
  284. #ifdef DEBUG
  285. OutputDebugString("ICSendMessage32: gfICM32 is not set - returning FALSE\n");
  286. #endif
  287. return ICERR_BADHANDLE;
  288. }
  289. return ((LRESULT)(pvth.lpfnCallproc32W)(compThunkICSendMessage32,
  290. (DWORD)hic,
  291. (DWORD)msg,
  292. (DWORD)dwP1,
  293. (DWORD)dwP2,
  294. pvth.lpICMThunkEntry,
  295. 0L, // no mapping of pointers
  296. 5L));
  297. }
  298. DWORD FAR PASCAL ICOpen32(DWORD fccType, DWORD fccHandler, UINT wMode)
  299. {
  300. /*
  301. * Check there's something on the other side!
  302. */
  303. if (!gfICM32) {
  304. #ifdef DEBUG
  305. OutputDebugString("ICOpen32: gfICM32 is not set - returning FALSE\n");
  306. #endif
  307. return NULL;
  308. }
  309. return ((DWORD)(pvth.lpfnCallproc32W)(compThunkICOpen32,
  310. (DWORD)fccType,
  311. (DWORD)fccHandler,
  312. (DWORD)wMode,
  313. (DWORD)0,
  314. pvth.lpICMThunkEntry,
  315. 0L, // no mapping of pointers
  316. 5L));
  317. }
  318. LRESULT FAR PASCAL ICClose32(DWORD hic)
  319. {
  320. /*
  321. * Check there's something on the other side!
  322. */
  323. if (!gfICM32) {
  324. #ifdef DEBUG
  325. OutputDebugString("ICClose32: gfICM32 is not set - returning FALSE\n");
  326. #endif
  327. return ICERR_BADHANDLE;
  328. }
  329. return ((LRESULT)(pvth.lpfnCallproc32W)(compThunkICClose32,
  330. (DWORD)hic,
  331. (DWORD)0,
  332. (DWORD)0,
  333. (DWORD)0,
  334. pvth.lpICMThunkEntry,
  335. 0L, // no mapping of pointers
  336. 5L));
  337. }
  338.