Windows2000/private/windows/media/avi/msvideo.16/thunk16.c
2020-09-30 17:12:32 +02:00

407 lines
12 KiB
C

/*
thunks.c
Contains code for thunking msvideo.dll from 16bit to 32bit
Copyright (c) Microsoft Corporation 1994. All rights reserved
Basic Structure:
When loaded, the 16 bit DLL will try to find the corresponding
32 bit DLL. There are two of these.
The 32bit videoXXXX api entry points are in AVICAP32.DLL
The 32bit ICM code is in MSVFW32.DLL
The thunk initialisation routine will check the code is running on
Windows NT. If not, no further initialisation is done. This
ensures that the same binary can be used on NT, and other Windows
platforms.
The code then attempts to access the special entry points provided
in KERNEL.DLL for loading and calling 32 bit entry points. If this
link fails, no thunking can be done.
Each of the 32 bit DLLs is loaded in turn, and GetProcAddress32 is
called for the special thunk entry point. If all works then two
global flags are set (independently of each other).
gfVideo32 == TRUE means that the videoXXXX apis can be called.
gfICM32 == TRUE means that the 32 bit ICM code is available.
*/
#include <windows.h>
#define MMNOMCI
#include <win32.h>
#include <mmsystem.h>
#include <msvideo.h>
#include <msviddrv.h>
#include <compman.h>
#include "vidthunk.h"
#include "msvideoi.h"
SZCODE gszKernel[] = TEXT("KERNEL");
SZCODE gszLoadLibraryEx32W[] = TEXT("LoadLibraryEx32W");
//SZCODE gszFreeLibraryEx32W[] = TEXT("FreeLibraryEx32W");
SZCODE gszFreeLibrary32W[] = TEXT("FreeLibrary32W");
SZCODE gszGetProcAddress32W[] = TEXT("GetProcAddress32W");
SZCODE gszCallproc32W[] = TEXT("CallProc32W");
SZCODE gszVideoThunkEntry[] = TEXT("videoThunk32");
SZCODE gszVideo32[] = TEXT("avicap32.dll");
SZCODE gszICMThunkEntry[] = TEXT("ICMThunk32");
SZCODE gszICMThunkEntry2[] = TEXT("ICMTHUNK32");
SZCODE gszICM32[] = TEXT("msvfw32.dll");
VIDTHUNK pvth;
#ifndef WIN32
//--------------------------------------------------------------------------;
// BOOL InitThunks
// Description:
// Arguments:
// None.
// Return (BOOL):
// History:
//--------------------------------------------------------------------------;
void FAR PASCAL InitThunks(VOID)
{
HMODULE hmodKernel;
DWORD (FAR PASCAL *lpfnLoadLibraryEx32W)(LPCSTR, DWORD, DWORD);
LPVOID (FAR PASCAL *lpfnGetProcAddress32W)(DWORD, LPCSTR);
DWORD (FAR PASCAL *lpfnFreeLibrary32W)(DWORD hLibModule);
// Check if we're WOW
// if (!(GetWinFlags() & WF_WINNT)) {
// //DPF(("Not running in WOW... returning FALSE\n"));
// return;
// }
// See if we can find the thunking routine entry points in KERNEL
hmodKernel = GetModuleHandle(gszKernel);
if (hmodKernel == NULL)
{
DPF(("Cannot link to kernel module... returning FALSE\n"));
return; // !!!!
}
*(FARPROC *)&lpfnLoadLibraryEx32W =
GetProcAddress(hmodKernel, gszLoadLibraryEx32W);
if (lpfnLoadLibraryEx32W == NULL)
{
DPF(("Cannot get address of LoadLibrary32... returning FALSE\n"));
return;
}
*(FARPROC *)&lpfnGetProcAddress32W =
GetProcAddress(hmodKernel, gszGetProcAddress32W);
if (lpfnGetProcAddress32W == NULL)
{
DPF(("Cannot get address of GetProcAddress32... returning FALSE\n"));
return;
}
*(FARPROC *)&pvth.lpfnCallproc32W =
GetProcAddress(hmodKernel, gszCallproc32W);
if (pvth.lpfnCallproc32W == NULL)
{
DPF(("Cannot get address of CallProc32... returning FALSE\n"));
return;
}
// In case we need to unload our 32 bit libraries...
*(FARPROC *)&lpfnFreeLibrary32W =
GetProcAddress(hmodKernel, gszFreeLibrary32W);
// See if we can get pointers to our thunking entry points
pvth.dwVideo32Handle = (*lpfnLoadLibraryEx32W)(gszVideo32, 0L, 0L);
if (pvth.dwVideo32Handle != 0)
{
pvth.lpVideoThunkEntry = (*lpfnGetProcAddress32W)(pvth.dwVideo32Handle, gszVideoThunkEntry);
if (pvth.lpVideoThunkEntry != NULL)
{
gfVideo32 = TRUE;
} else {
DPF(("Cannot get address of video thunk entry...\n"));
if (lpfnFreeLibrary32W)
{
(*lpfnFreeLibrary32W)(pvth.dwVideo32Handle);
}
}
} else {
DPF(("Cannot load Video32 DLL...\n"));
}
pvth.dwICM32Handle = (*lpfnLoadLibraryEx32W)(gszICM32, 0L, 0L);
if (pvth.dwICM32Handle != 0)
{
pvth.lpICMThunkEntry = (*lpfnGetProcAddress32W)(pvth.dwICM32Handle, gszICMThunkEntry);
if (pvth.lpICMThunkEntry != NULL)
{
DPF(("ICM thunks OK!!\n"));
gfICM32 = TRUE;
} else {
DPF(("Cannot get address of ICM thunk entry... trying #2\n"));
pvth.lpICMThunkEntry = (*lpfnGetProcAddress32W)(pvth.dwICM32Handle, gszICMThunkEntry2);
if (pvth.lpICMThunkEntry != NULL)
{
DPF(("ICM thunks OK!! (at second time of trying)\n"));
gfICM32 = TRUE;
} else {
DPF(("Cannot get address of ICM thunk entry2...\n"));
if (lpfnFreeLibrary32W)
{
(*lpfnFreeLibrary32W)(pvth.dwICM32Handle);
}
}
}
} else {
DPF(("Cannot load ICM32 DLL...\n"));
}
return;
}
#endif // !WIN32
// The following functions generate calls to the 32-bit side
DWORD FAR PASCAL videoMessage32(HVIDEO hVideo, UINT msg, DWORD dwP1, DWORD dwP2)
{
/*
* Check there's something on the other side!
*/
if (!gfVideo32) {
DPF(("videoMessage32 - no video thunks... returning FALSE\n"));
return DV_ERR_INVALHANDLE;
}
/*
* Watch out for hvideos being passed
*/
if (msg == DVM_STREAM_INIT) {
((LPVIDEO_STREAM_INIT_PARMS)dwP1)->hVideo = hVideo;
}
return((DWORD)(pvth.lpfnCallproc32W)(vidThunkvideoMessage32,
(DWORD)hVideo,
(DWORD)msg,
(DWORD)dwP1,
(DWORD)dwP2,
pvth.lpVideoThunkEntry,
0L, // no mapping of pointers
5L));
}
DWORD FAR PASCAL videoGetNumDevs32(void)
{
if (!gfVideo32) {
DPF(("videoGetNumDevs32 - no video thunks... returning FALSE\n"));
return 0;
}
return((DWORD)(pvth.lpfnCallproc32W)(vidThunkvideoGetNumDevs32,
(DWORD)0,
(DWORD)0,
(DWORD)0,
(DWORD)0,
pvth.lpVideoThunkEntry,
0L, // no mapping of pointers
5L));
}
DWORD FAR PASCAL videoClose32(HVIDEO hVideo)
{
/*
* Check there's something on the other side!
*/
if (!gfVideo32) {
DPF(("videoClose32 - no video thunks... returning FALSE\n"));
return DV_ERR_INVALHANDLE;
}
return((DWORD)(pvth.lpfnCallproc32W)(vidThunkvideoClose32,
(DWORD)hVideo,
(DWORD)0,
(DWORD)0,
(DWORD)0,
pvth.lpVideoThunkEntry,
0L, // no mapping of pointers
5L));
}
DWORD FAR PASCAL videoOpen32(LPHVIDEO lphVideo, DWORD dwDeviceID, DWORD dwFlags)
{
DWORD dwRetc;
if (!gfVideo32) {
DPF(("videoOpen32 - no video thunks... returning FALSE\n"));
return DV_ERR_NOTDETECTED;
}
dwRetc = ((DWORD)(pvth.lpfnCallproc32W)(vidThunkvideoOpen32,
(DWORD)lphVideo,
(DWORD)dwDeviceID,
(DWORD)dwFlags,
(DWORD)0,
pvth.lpVideoThunkEntry,
0L, // no mapping of pointers
5L));
if (dwRetc == DV_ERR_OK) {
#ifdef DEBUG
if (Is32bitHandle(*lphVideo)) {
//OutputDebugString("\nMSVIDEO : 32-bit handle does not fit in 16 bits!");
DebugBreak();
}
#endif
*lphVideo = Make32bitHandle(*lphVideo);
}
return dwRetc;
}
DWORD FAR PASCAL videoGetDriverDesc32(DWORD wDriverIndex,
LPSTR lpszName, short cbName,
LPSTR lpszVer, short cbVer)
{
if (!gfVideo32) {
DPF(("videoGetDriverDesc32 - no video thunks... returning FALSE\n"));
return DV_ERR_NOTDETECTED;
}
return (BOOL)(pvth.lpfnCallproc32W)(vidThunkvideoGetDriverDesc32,
(DWORD)wDriverIndex,
(DWORD)lpszName,
(DWORD)lpszVer,
(DWORD) MAKELONG(cbName, cbVer),
pvth.lpVideoThunkEntry,
0L, // no mapping of pointers
5L); // 5 params
}
/*
* The ICM thunking uses the same mechanism as for Video, but calls to a
* different 32 bit DLL.
*/
BOOL FAR PASCAL ICInfo32(DWORD fccType, DWORD fccHandler, ICINFO FAR * lpicInfo)
{
if (!gfICM32) {
//OutputDebugString("ICInfo32: gfICM32 is not set - returning FALSE\n");
return FALSE;
}
return ((BOOL)(pvth.lpfnCallproc32W)(compThunkICInfo32,
(DWORD)fccType,
(DWORD)fccHandler,
(DWORD)lpicInfo,
(DWORD)0,
pvth.lpICMThunkEntry,
0L, // no mapping of pointers
5L));
}
LRESULT FAR PASCAL ICSendMessage32(DWORD hic, UINT msg, DWORD dwP1, DWORD dwP2)
{
/*
* Check there's something on the other side!
*/
if (!gfICM32) {
#ifdef DEBUG
OutputDebugString("ICSendMessage32: gfICM32 is not set - returning FALSE\n");
#endif
return ICERR_BADHANDLE;
}
return ((LRESULT)(pvth.lpfnCallproc32W)(compThunkICSendMessage32,
(DWORD)hic,
(DWORD)msg,
(DWORD)dwP1,
(DWORD)dwP2,
pvth.lpICMThunkEntry,
0L, // no mapping of pointers
5L));
}
DWORD FAR PASCAL ICOpen32(DWORD fccType, DWORD fccHandler, UINT wMode)
{
/*
* Check there's something on the other side!
*/
if (!gfICM32) {
#ifdef DEBUG
OutputDebugString("ICOpen32: gfICM32 is not set - returning FALSE\n");
#endif
return NULL;
}
return ((DWORD)(pvth.lpfnCallproc32W)(compThunkICOpen32,
(DWORD)fccType,
(DWORD)fccHandler,
(DWORD)wMode,
(DWORD)0,
pvth.lpICMThunkEntry,
0L, // no mapping of pointers
5L));
}
LRESULT FAR PASCAL ICClose32(DWORD hic)
{
/*
* Check there's something on the other side!
*/
if (!gfICM32) {
#ifdef DEBUG
OutputDebugString("ICClose32: gfICM32 is not set - returning FALSE\n");
#endif
return ICERR_BADHANDLE;
}
return ((LRESULT)(pvth.lpfnCallproc32W)(compThunkICClose32,
(DWORD)hic,
(DWORD)0,
(DWORD)0,
(DWORD)0,
pvth.lpICMThunkEntry,
0L, // no mapping of pointers
5L));
}