mirror of https://github.com/PCSX2/pcsx2.git
269 lines
6.3 KiB
C++
269 lines
6.3 KiB
C++
|
#include <windows.h>
|
||
|
#include "iasiodrv.h"
|
||
|
#include "asiolist.h"
|
||
|
|
||
|
#define ASIODRV_DESC "description"
|
||
|
#define INPROC_SERVER "InprocServer32"
|
||
|
#define ASIO_PATH "software\\asio"
|
||
|
#define COM_CLSID "clsid"
|
||
|
|
||
|
// ******************************************************************
|
||
|
// Local Functions
|
||
|
// ******************************************************************
|
||
|
static LONG findDrvPath (char *clsidstr,char *dllpath,int dllpathsize)
|
||
|
{
|
||
|
HKEY hkEnum,hksub,hkpath;
|
||
|
char databuf[512];
|
||
|
LONG cr,rc = -1;
|
||
|
DWORD datatype,datasize;
|
||
|
DWORD index;
|
||
|
OFSTRUCT ofs;
|
||
|
HFILE hfile;
|
||
|
BOOL found = FALSE;
|
||
|
|
||
|
CharLowerBuff(clsidstr,strlen(clsidstr));
|
||
|
if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) {
|
||
|
|
||
|
index = 0;
|
||
|
while (cr == ERROR_SUCCESS && !found) {
|
||
|
cr = RegEnumKey(hkEnum,index++,(LPTSTR)databuf,512);
|
||
|
if (cr == ERROR_SUCCESS) {
|
||
|
CharLowerBuff(databuf,strlen(databuf));
|
||
|
if (!(strcmp(databuf,clsidstr))) {
|
||
|
if ((cr = RegOpenKeyEx(hkEnum,(LPCTSTR)databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
|
||
|
if ((cr = RegOpenKeyEx(hksub,(LPCTSTR)INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) {
|
||
|
datatype = REG_SZ; datasize = (DWORD)dllpathsize;
|
||
|
cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize);
|
||
|
if (cr == ERROR_SUCCESS) {
|
||
|
memset(&ofs,0,sizeof(OFSTRUCT));
|
||
|
ofs.cBytes = sizeof(OFSTRUCT);
|
||
|
hfile = OpenFile(dllpath,&ofs,OF_EXIST);
|
||
|
if (hfile) rc = 0;
|
||
|
}
|
||
|
RegCloseKey(hkpath);
|
||
|
}
|
||
|
RegCloseKey(hksub);
|
||
|
}
|
||
|
found = TRUE; // break out
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
RegCloseKey(hkEnum);
|
||
|
}
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
|
||
|
static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv)
|
||
|
{
|
||
|
HKEY hksub;
|
||
|
char databuf[256];
|
||
|
char dllpath[MAXPATHLEN];
|
||
|
WORD wData[100];
|
||
|
CLSID clsid;
|
||
|
DWORD datatype,datasize;
|
||
|
LONG cr,rc;
|
||
|
|
||
|
if (!lpdrv) {
|
||
|
if ((cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
|
||
|
|
||
|
datatype = REG_SZ; datasize = 256;
|
||
|
cr = RegQueryValueEx(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize);
|
||
|
if (cr == ERROR_SUCCESS) {
|
||
|
rc = findDrvPath (databuf,dllpath,MAXPATHLEN);
|
||
|
if (rc == 0) {
|
||
|
lpdrv = new ASIODRVSTRUCT[1];
|
||
|
if (lpdrv) {
|
||
|
memset(lpdrv,0,sizeof(ASIODRVSTRUCT));
|
||
|
lpdrv->drvID = drvID;
|
||
|
MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100);
|
||
|
if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) {
|
||
|
memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID));
|
||
|
}
|
||
|
|
||
|
datatype = REG_SZ; datasize = 256;
|
||
|
cr = RegQueryValueEx(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize);
|
||
|
if (cr == ERROR_SUCCESS) {
|
||
|
strncpy(lpdrv->drvname,databuf,127);
|
||
|
}
|
||
|
else strcpy(lpdrv->drvname,keyname);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
RegCloseKey(hksub);
|
||
|
}
|
||
|
}
|
||
|
else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next);
|
||
|
|
||
|
return lpdrv;
|
||
|
}
|
||
|
|
||
|
static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv)
|
||
|
{
|
||
|
IASIO *iasio;
|
||
|
|
||
|
if (lpdrv != 0) {
|
||
|
deleteDrvStruct(lpdrv->next);
|
||
|
if (lpdrv->asiodrv) {
|
||
|
iasio = (IASIO *)lpdrv->asiodrv;
|
||
|
iasio->Release();
|
||
|
}
|
||
|
delete lpdrv;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv)
|
||
|
{
|
||
|
while (lpdrv) {
|
||
|
if (lpdrv->drvID == drvID) return lpdrv;
|
||
|
lpdrv = lpdrv->next;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
// ******************************************************************
|
||
|
|
||
|
|
||
|
// ******************************************************************
|
||
|
// AsioDriverList
|
||
|
// ******************************************************************
|
||
|
AsioDriverList::AsioDriverList ()
|
||
|
{
|
||
|
HKEY hkEnum = 0;
|
||
|
char keyname[MAXDRVNAMELEN];
|
||
|
LPASIODRVSTRUCT pdl;
|
||
|
LONG cr;
|
||
|
DWORD index = 0;
|
||
|
BOOL fin = FALSE;
|
||
|
|
||
|
numdrv = 0;
|
||
|
lpdrvlist = 0;
|
||
|
|
||
|
cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum);
|
||
|
while (cr == ERROR_SUCCESS) {
|
||
|
if ((cr = RegEnumKey(hkEnum,index++,(LPTSTR)keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) {
|
||
|
lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist);
|
||
|
}
|
||
|
else fin = TRUE;
|
||
|
}
|
||
|
if (hkEnum) RegCloseKey(hkEnum);
|
||
|
|
||
|
pdl = lpdrvlist;
|
||
|
while (pdl) {
|
||
|
numdrv++;
|
||
|
pdl = pdl->next;
|
||
|
}
|
||
|
|
||
|
if (numdrv) CoInitialize(0); // initialize COM
|
||
|
}
|
||
|
|
||
|
AsioDriverList::~AsioDriverList ()
|
||
|
{
|
||
|
if (numdrv) {
|
||
|
deleteDrvStruct(lpdrvlist);
|
||
|
CoUninitialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
LONG AsioDriverList::asioGetNumDev (VOID)
|
||
|
{
|
||
|
return (LONG)numdrv;
|
||
|
}
|
||
|
|
||
|
|
||
|
LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv)
|
||
|
{
|
||
|
LPASIODRVSTRUCT lpdrv = 0;
|
||
|
long rc;
|
||
|
|
||
|
if (!asiodrv) return DRVERR_INVALID_PARAM;
|
||
|
|
||
|
if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
|
||
|
if (!lpdrv->asiodrv) {
|
||
|
rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv);
|
||
|
if (rc == S_OK) {
|
||
|
lpdrv->asiodrv = *asiodrv;
|
||
|
return 0;
|
||
|
}
|
||
|
// else if (rc == REGDB_E_CLASSNOTREG)
|
||
|
// strcpy (info->messageText, "Driver not registered in the Registration Database!");
|
||
|
}
|
||
|
else rc = DRVERR_DEVICE_ALREADY_OPEN;
|
||
|
}
|
||
|
else rc = DRVERR_DEVICE_NOT_FOUND;
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
|
||
|
LONG AsioDriverList::asioCloseDriver (int drvID)
|
||
|
{
|
||
|
LPASIODRVSTRUCT lpdrv = 0;
|
||
|
IASIO *iasio;
|
||
|
|
||
|
if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
|
||
|
if (lpdrv->asiodrv) {
|
||
|
iasio = (IASIO *)lpdrv->asiodrv;
|
||
|
iasio->Release();
|
||
|
lpdrv->asiodrv = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize)
|
||
|
{
|
||
|
LPASIODRVSTRUCT lpdrv = 0;
|
||
|
|
||
|
if (!drvname) return DRVERR_INVALID_PARAM;
|
||
|
|
||
|
if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
|
||
|
if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) {
|
||
|
strcpy(drvname,lpdrv->drvname);
|
||
|
}
|
||
|
else {
|
||
|
memcpy(drvname,lpdrv->drvname,drvnamesize-4);
|
||
|
drvname[drvnamesize-4] = '.';
|
||
|
drvname[drvnamesize-3] = '.';
|
||
|
drvname[drvnamesize-2] = '.';
|
||
|
drvname[drvnamesize-1] = 0;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
return DRVERR_DEVICE_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize)
|
||
|
{
|
||
|
LPASIODRVSTRUCT lpdrv = 0;
|
||
|
|
||
|
if (!dllpath) return DRVERR_INVALID_PARAM;
|
||
|
|
||
|
if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
|
||
|
if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) {
|
||
|
strcpy(dllpath,lpdrv->dllpath);
|
||
|
return 0;
|
||
|
}
|
||
|
dllpath[0] = 0;
|
||
|
return DRVERR_INVALID_PARAM;
|
||
|
}
|
||
|
return DRVERR_DEVICE_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid)
|
||
|
{
|
||
|
LPASIODRVSTRUCT lpdrv = 0;
|
||
|
|
||
|
if (!clsid) return DRVERR_INVALID_PARAM;
|
||
|
|
||
|
if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
|
||
|
memcpy(clsid,&lpdrv->clsid,sizeof(CLSID));
|
||
|
return 0;
|
||
|
}
|
||
|
return DRVERR_DEVICE_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
|