mirror of https://github.com/mpv-player/mpv
200 lines
4.4 KiB
C
200 lines
4.4 KiB
C
/*
|
|
* Modified for use with MPlayer, detailed changelog at
|
|
* http://svn.mplayerhq.hu/mplayer/trunk/
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "debug.h"
|
|
|
|
#include <stdio.h>
|
|
#if HAVE_MALLOC_H
|
|
#include <malloc.h>
|
|
#endif
|
|
#include <stdlib.h>
|
|
#ifdef __FreeBSD__
|
|
#include <sys/time.h>
|
|
#endif
|
|
|
|
#include "win32.h"
|
|
#include "wine/driver.h"
|
|
#include "wine/pe_image.h"
|
|
#include "wine/winreg.h"
|
|
#include "wine/vfw.h"
|
|
#include "registry.h"
|
|
#ifdef WIN32_LOADER
|
|
#include "ldt_keeper.h"
|
|
#endif
|
|
#include "drv.h"
|
|
#ifndef __MINGW32__
|
|
#include "ext.h"
|
|
#endif
|
|
|
|
#ifndef WIN32_LOADER
|
|
char* def_path=WIN32_PATH;
|
|
#else
|
|
extern char* def_path;
|
|
#endif
|
|
|
|
#if 1
|
|
|
|
/*
|
|
* STORE_ALL/REST_ALL seems like an attempt to workaround problems due to
|
|
* WINAPI/no-WINAPI bustage.
|
|
*
|
|
* There should be no need for the STORE_ALL/REST_ALL hack once all
|
|
* function definitions agree with their prototypes (WINAPI-wise) and
|
|
* we make sure, that we do not call these functions without a proper
|
|
* prototype in scope.
|
|
*/
|
|
|
|
#define STORE_ALL
|
|
#define REST_ALL
|
|
#else
|
|
// this asm code is no longer needed
|
|
#define STORE_ALL \
|
|
__asm__ volatile ( \
|
|
"push %%ebx\n\t" \
|
|
"push %%ecx\n\t" \
|
|
"push %%edx\n\t" \
|
|
"push %%esi\n\t" \
|
|
"push %%edi\n\t"::)
|
|
|
|
#define REST_ALL \
|
|
__asm__ volatile ( \
|
|
"pop %%edi\n\t" \
|
|
"pop %%esi\n\t" \
|
|
"pop %%edx\n\t" \
|
|
"pop %%ecx\n\t" \
|
|
"pop %%ebx\n\t"::)
|
|
#endif
|
|
|
|
static int needs_free=0;
|
|
void SetCodecPath(const char* path)
|
|
{
|
|
if(needs_free)free(def_path);
|
|
if(path==0)
|
|
{
|
|
def_path=WIN32_PATH;
|
|
needs_free=0;
|
|
return;
|
|
}
|
|
def_path = (char*) malloc(strlen(path)+1);
|
|
strcpy(def_path, path);
|
|
needs_free=1;
|
|
}
|
|
|
|
static DWORD dwDrvID = 0;
|
|
|
|
LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT message,
|
|
LPARAM lParam1, LPARAM lParam2)
|
|
{
|
|
DRVR* module=(DRVR*)hDriver;
|
|
int result;
|
|
#ifndef __svr4__
|
|
char qw[300];
|
|
#endif
|
|
#ifdef DETAILED_OUT
|
|
printf("SendDriverMessage: driver %X, message %X, arg1 %X, arg2 %X\n", hDriver, message, lParam1, lParam2);
|
|
#endif
|
|
if (!module || !module->hDriverModule || !module->DriverProc) return -1;
|
|
#ifndef __svr4__
|
|
__asm__ volatile ("fsave (%0)\n\t": :"r"(&qw));
|
|
#endif
|
|
|
|
#ifdef WIN32_LOADER
|
|
Setup_FS_Segment();
|
|
#endif
|
|
|
|
STORE_ALL;
|
|
result=module->DriverProc(module->dwDriverID, hDriver, message, lParam1, lParam2);
|
|
REST_ALL;
|
|
|
|
#ifndef __svr4__
|
|
__asm__ volatile ("frstor (%0)\n\t": :"r"(&qw));
|
|
#endif
|
|
|
|
#ifdef DETAILED_OUT
|
|
printf("\t\tResult: %X\n", result);
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
void DrvClose(HDRVR hDriver)
|
|
{
|
|
if (hDriver)
|
|
{
|
|
DRVR* d = (DRVR*)hDriver;
|
|
if (d->hDriverModule)
|
|
{
|
|
#ifdef WIN32_LOADER
|
|
Setup_FS_Segment();
|
|
#endif
|
|
if (d->DriverProc)
|
|
{
|
|
SendDriverMessage(hDriver, DRV_CLOSE, 0, 0);
|
|
d->dwDriverID = 0;
|
|
SendDriverMessage(hDriver, DRV_FREE, 0, 0);
|
|
}
|
|
FreeLibrary(d->hDriverModule);
|
|
}
|
|
free(d);
|
|
}
|
|
#ifdef WIN32_LOADER
|
|
CodecRelease();
|
|
#endif
|
|
}
|
|
|
|
//DrvOpen(LPCSTR lpszDriverName, LPCSTR lpszSectionName, LPARAM lParam2)
|
|
HDRVR DrvOpen(LPARAM lParam2)
|
|
{
|
|
NPDRVR hDriver;
|
|
char unknown[0x124];
|
|
const char* filename = (const char*) ((ICOPEN*) lParam2)->pV1Reserved;
|
|
|
|
#ifdef WIN32_LOADER
|
|
Setup_LDT_Keeper();
|
|
#endif
|
|
printf("Loading codec DLL: '%s'\n",filename);
|
|
|
|
hDriver = (NPDRVR) malloc(sizeof(DRVR));
|
|
if (!hDriver)
|
|
return (HDRVR) 0;
|
|
memset((void*)hDriver, 0, sizeof(DRVR));
|
|
|
|
#ifdef WIN32_LOADER
|
|
CodecAlloc();
|
|
Setup_FS_Segment();
|
|
#endif
|
|
|
|
hDriver->hDriverModule = LoadLibraryA(filename);
|
|
if (!hDriver->hDriverModule)
|
|
{
|
|
printf("Can't open library %s\n", filename);
|
|
DrvClose((HDRVR)hDriver);
|
|
return (HDRVR) 0;
|
|
}
|
|
|
|
hDriver->DriverProc = (DRIVERPROC) GetProcAddress(hDriver->hDriverModule,
|
|
"DriverProc");
|
|
if (!hDriver->DriverProc)
|
|
{
|
|
printf("Library %s is not a valid VfW/ACM codec\n", filename);
|
|
DrvClose((HDRVR)hDriver);
|
|
return (HDRVR) 0;
|
|
}
|
|
|
|
TRACE("DriverProc == %X\n", hDriver->DriverProc);
|
|
SendDriverMessage((HDRVR)hDriver, DRV_LOAD, 0, 0);
|
|
TRACE("DRV_LOAD Ok!\n");
|
|
SendDriverMessage((HDRVR)hDriver, DRV_ENABLE, 0, 0);
|
|
TRACE("DRV_ENABLE Ok!\n");
|
|
hDriver->dwDriverID = ++dwDrvID; // generate new id
|
|
|
|
// open driver and remmeber proper DriverID
|
|
hDriver->dwDriverID = SendDriverMessage((HDRVR)hDriver, DRV_OPEN, (LPARAM) unknown, lParam2);
|
|
TRACE("DRV_OPEN Ok!(%X)\n", hDriver->dwDriverID);
|
|
|
|
printf("Loaded DLL driver %s at %x\n", filename, hDriver->hDriverModule);
|
|
return (HDRVR)hDriver;
|
|
}
|