mirror of https://github.com/PCSX2/pcsx2.git
333 lines
9.0 KiB
C++
333 lines
9.0 KiB
C++
#include <windows.h>
|
|
#include <stdio.h>
|
|
|
|
typedef struct keylist
|
|
{
|
|
HKEY mainKey;
|
|
HKEY subKey;
|
|
char *keyname;
|
|
struct keylist *next;
|
|
} KEYLIST, *LPKEYLIST;
|
|
|
|
#define CLSID_STRING_LEN 100
|
|
#define MAX_PATH_LEN 360
|
|
|
|
#define DEV_ERR_SELFREG -100
|
|
#define ERRSREG_MODULE_NOT_FOUND DEV_ERR_SELFREG-1
|
|
#define ERRSREG_MODPATH_NOT_FOUND DEV_ERR_SELFREG-2
|
|
#define ERRSREG_STRING_FROM_CLSID DEV_ERR_SELFREG-3
|
|
#define ERRSREG_CHAR_TO_MULTIBYTE DEV_ERR_SELFREG-4
|
|
|
|
#define SZREGSTR_DESCRIPTION "Description"
|
|
#define SZREGSTR_CLSID "CLSID"
|
|
#define SZREGSTR_INPROCSERVER32 "InprocServer32"
|
|
#define SZREGSTR_THREADINGMODEL "ThreadingModel"
|
|
#define SZREGSTR_SOFTWARE "SOFTWARE"
|
|
#define SZREGSTR_ASIO "ASIO"
|
|
|
|
LONG RegisterAsioDriver (CLSID,char *,char *,char *,char *);
|
|
LONG UnregisterAsioDriver (CLSID,char *,char *);
|
|
|
|
static LONG findRegPath (HKEY,char *);
|
|
static LONG createRegPath (HKEY,char *,char *);
|
|
static LONG createRegStringValue (HKEY,char *,char *,char *);
|
|
static LONG getRegString (HKEY,char *,char *,LPVOID,DWORD);
|
|
static LPKEYLIST findAllSubKeys (HKEY,HKEY,DWORD,char *,LPKEYLIST);
|
|
static LONG deleteRegPath (HKEY,char *,char *);
|
|
|
|
static char subkeybuf[MAX_PATH_LEN];
|
|
|
|
|
|
// ------------------------------------------
|
|
// Global Functions
|
|
// ------------------------------------------
|
|
LONG RegisterAsioDriver (CLSID clsid,char *szdllname,char *szregname,char *szasiodesc,char *szthreadmodel)
|
|
{
|
|
HMODULE hMod;
|
|
char szDLLPath[MAX_PATH_LEN];
|
|
char szModuleName[MAX_PATH_LEN];
|
|
char szregpath[MAX_PATH_LEN];
|
|
char szclsid[CLSID_STRING_LEN];
|
|
LPOLESTR wszCLSID = NULL;
|
|
BOOL newregentry = FALSE;
|
|
LONG rc;
|
|
|
|
hMod = GetModuleHandle(szdllname);
|
|
if (!hMod) return ERRSREG_MODULE_NOT_FOUND;
|
|
szModuleName[0] = 0;
|
|
GetModuleFileName(hMod,szModuleName,MAX_PATH_LEN);
|
|
if (!szModuleName[0]) return ERRSREG_MODPATH_NOT_FOUND;
|
|
CharLower((LPTSTR)szModuleName);
|
|
|
|
rc = (LONG)StringFromCLSID(clsid,&wszCLSID);
|
|
if (rc != S_OK) return ERRSREG_STRING_FROM_CLSID;
|
|
rc = (LONG)WideCharToMultiByte(CP_ACP,0,(LPWSTR)wszCLSID,-1,szclsid,CLSID_STRING_LEN,0,0);
|
|
if (!rc) return ERRSREG_CHAR_TO_MULTIBYTE;
|
|
|
|
sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid);
|
|
rc = findRegPath(HKEY_CLASSES_ROOT,szregpath);
|
|
if (rc) {
|
|
sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_CLSID,szclsid,SZREGSTR_INPROCSERVER32);
|
|
getRegString (HKEY_CLASSES_ROOT,szregpath,0,(LPVOID)szDLLPath,MAX_PATH_LEN);
|
|
CharLower((LPTSTR)szDLLPath);
|
|
rc = (LONG)strcmp(szDLLPath,szModuleName);
|
|
if (rc) {
|
|
// delete old regentry
|
|
sprintf(szregpath,"%s",SZREGSTR_CLSID);
|
|
deleteRegPath(HKEY_CLASSES_ROOT,szregpath,szclsid);
|
|
newregentry = TRUE;
|
|
}
|
|
}
|
|
else newregentry = TRUE;
|
|
|
|
if (newregentry) {
|
|
// HKEY_CLASSES_ROOT\CLSID\{...}
|
|
sprintf(szregpath,"%s",SZREGSTR_CLSID);
|
|
createRegPath (HKEY_CLASSES_ROOT,szregpath,szclsid);
|
|
// HKEY_CLASSES_ROOT\CLSID\{...} -> Description
|
|
sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid);
|
|
createRegStringValue(HKEY_CLASSES_ROOT,szregpath,0,szasiodesc);
|
|
// HKEY_CLASSES_ROOT\CLSID\InProcServer32
|
|
sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid);
|
|
createRegPath (HKEY_CLASSES_ROOT,szregpath,SZREGSTR_INPROCSERVER32);
|
|
// HKEY_CLASSES_ROOT\CLSID\InProcServer32 -> DLL path
|
|
sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_CLSID,szclsid,SZREGSTR_INPROCSERVER32);
|
|
createRegStringValue(HKEY_CLASSES_ROOT,szregpath,0,szModuleName);
|
|
// HKEY_CLASSES_ROOT\CLSID\InProcServer32 -> ThreadingModel
|
|
createRegStringValue(HKEY_CLASSES_ROOT,szregpath,SZREGSTR_THREADINGMODEL,szthreadmodel);
|
|
}
|
|
|
|
// HKEY_LOCAL_MACHINE\SOFTWARE\ASIO
|
|
sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO);
|
|
rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath);
|
|
if (rc) {
|
|
sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO,szregname);
|
|
rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath);
|
|
if (rc) {
|
|
sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO);
|
|
deleteRegPath(HKEY_LOCAL_MACHINE,szregpath,szregname);
|
|
}
|
|
}
|
|
else {
|
|
// HKEY_LOCAL_MACHINE\SOFTWARE\ASIO
|
|
sprintf(szregpath,"%s",SZREGSTR_SOFTWARE);
|
|
createRegPath (HKEY_LOCAL_MACHINE,szregpath,SZREGSTR_ASIO);
|
|
}
|
|
|
|
// HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\<szregname>
|
|
sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO);
|
|
createRegPath (HKEY_LOCAL_MACHINE,szregpath,szregname);
|
|
|
|
// HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\<szregname> -> CLSID
|
|
// HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\<szregname> -> Description
|
|
sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO,szregname);
|
|
createRegStringValue(HKEY_LOCAL_MACHINE,szregpath,SZREGSTR_CLSID,szclsid);
|
|
createRegStringValue(HKEY_LOCAL_MACHINE,szregpath,SZREGSTR_DESCRIPTION,szasiodesc);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
LONG UnregisterAsioDriver (CLSID clsid,char *szdllname,char *szregname)
|
|
{
|
|
LONG rc;
|
|
HMODULE hMod;
|
|
char szregpath[MAX_PATH_LEN];
|
|
char szModuleName[MAX_PATH_LEN];
|
|
char szclsid[CLSID_STRING_LEN];
|
|
LPOLESTR wszCLSID = NULL;
|
|
|
|
|
|
hMod = GetModuleHandle(szdllname);
|
|
if (!hMod) return ERRSREG_MODULE_NOT_FOUND;
|
|
szModuleName[0] = 0;
|
|
GetModuleFileName(hMod,szModuleName,MAX_PATH_LEN);
|
|
if (!szModuleName[0]) return ERRSREG_MODPATH_NOT_FOUND;
|
|
CharLower((LPTSTR)szModuleName);
|
|
|
|
rc = (LONG)StringFromCLSID(clsid,&wszCLSID) ;
|
|
if (rc != S_OK) return ERRSREG_STRING_FROM_CLSID;
|
|
rc = (LONG)WideCharToMultiByte(CP_ACP,0,(LPWSTR)wszCLSID,-1,szclsid,CLSID_STRING_LEN,0,0);
|
|
if (!rc) return ERRSREG_CHAR_TO_MULTIBYTE;
|
|
|
|
|
|
sprintf(szregpath,"%s\\%s",SZREGSTR_CLSID,szclsid);
|
|
rc = findRegPath(HKEY_CLASSES_ROOT,szregpath);
|
|
if (rc) {
|
|
// delete old regentry
|
|
sprintf(szregpath,"%s",SZREGSTR_CLSID);
|
|
deleteRegPath(HKEY_CLASSES_ROOT,szregpath,szclsid);
|
|
}
|
|
|
|
|
|
// HKEY_LOCAL_MACHINE\SOFTWARE\ASIO
|
|
sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO);
|
|
rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath);
|
|
if (rc) {
|
|
sprintf(szregpath,"%s\\%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO,szregname);
|
|
rc = findRegPath(HKEY_LOCAL_MACHINE,szregpath);
|
|
if (rc) {
|
|
sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO);
|
|
deleteRegPath(HKEY_LOCAL_MACHINE,szregpath,szregname);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// ------------------------------------------
|
|
// Local Functions
|
|
// ------------------------------------------
|
|
static LONG findRegPath (HKEY mainkey,char *szregpath)
|
|
{
|
|
HKEY hkey;
|
|
LONG cr,rc = -1;
|
|
|
|
if (szregpath) {
|
|
if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) {
|
|
RegCloseKey(hkey);
|
|
rc = 1;
|
|
}
|
|
else rc = 0;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static LONG createRegPath (HKEY mainkey,char *szregpath,char *sznewpath)
|
|
{
|
|
HKEY hkey,hksub;
|
|
LONG cr,rc = -1;
|
|
char newregpath[MAX_PATH_LEN];
|
|
|
|
sprintf(newregpath,"%s\\%s",szregpath,sznewpath);
|
|
if (!(cr = findRegPath(mainkey,newregpath))) {
|
|
if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) {
|
|
if ((cr = RegCreateKey(hkey,sznewpath,&hksub)) == ERROR_SUCCESS) {
|
|
RegCloseKey(hksub);
|
|
rc = 0;
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
else if (cr > 0) rc = 0;
|
|
|
|
return rc;
|
|
}
|
|
|
|
static LONG createRegStringValue (HKEY mainkey,char *szregpath,char *valname,char *szvalstr)
|
|
{
|
|
LONG cr,rc = -1;
|
|
HKEY hkey;
|
|
|
|
if (szregpath) {
|
|
if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) {
|
|
cr = RegSetValueEx(hkey,(LPCTSTR)valname,0,REG_SZ,(const BYTE *)szvalstr,(DWORD)strlen(szvalstr));
|
|
RegCloseKey(hkey);
|
|
if (cr == ERROR_SUCCESS) rc = 0;
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
static LONG getRegString (HKEY mainkey,char *szregpath,char *valname,LPVOID pval,DWORD vsize)
|
|
{
|
|
HKEY hkey;
|
|
LONG cr,rc = -1;
|
|
DWORD hsize,htype;
|
|
|
|
if (szregpath) {
|
|
if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) {
|
|
cr = RegQueryValueEx(hkey,valname,0,&htype,0,&hsize);
|
|
if (cr == ERROR_SUCCESS) {
|
|
if (hsize <= vsize) {
|
|
cr = RegQueryValueEx(hkey,valname,0,&htype,(LPBYTE)pval,&hsize);
|
|
rc = 0;
|
|
}
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
static LPKEYLIST findAllSubKeys (HKEY hkey,HKEY hksub,DWORD index,char *keyname,LPKEYLIST kl)
|
|
{
|
|
HKEY hknew = 0;
|
|
char *newkey;
|
|
LONG cr;
|
|
|
|
if (!hksub) {
|
|
cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_ALL_ACCESS,&hknew);
|
|
if (cr != ERROR_SUCCESS) return kl;
|
|
}
|
|
else hknew = hksub;
|
|
|
|
cr = RegEnumKey(hknew,index,(LPTSTR)subkeybuf,MAX_PATH_LEN);
|
|
if (cr == ERROR_SUCCESS) {
|
|
newkey = new char[strlen(subkeybuf)+1];
|
|
strcpy(newkey,subkeybuf);
|
|
|
|
kl = findAllSubKeys(hknew,0,0,newkey,kl);
|
|
kl = findAllSubKeys(hkey,hknew,index+1,keyname,kl);
|
|
|
|
return kl;
|
|
|
|
}
|
|
|
|
if (!kl->next) {
|
|
kl->next = new KEYLIST[1];
|
|
kl = kl->next;
|
|
kl->mainKey = hkey;
|
|
kl->subKey = hknew;
|
|
kl->keyname = keyname;
|
|
kl->next = 0;
|
|
}
|
|
|
|
return kl;
|
|
}
|
|
|
|
static LONG deleteRegPath (HKEY mainkey,char *szregpath,char *szdelpath)
|
|
{
|
|
HKEY hkey;
|
|
LONG cr,rc = -1;
|
|
KEYLIST klist;
|
|
LPKEYLIST pkl,k;
|
|
char *keyname = 0;
|
|
|
|
if ((cr = RegOpenKey(mainkey,szregpath,&hkey)) == ERROR_SUCCESS) {
|
|
|
|
keyname = new char[strlen(szdelpath)+1];
|
|
if (!keyname) {
|
|
RegCloseKey(hkey);
|
|
return rc;
|
|
}
|
|
strcpy(keyname,szdelpath);
|
|
klist.next = 0;
|
|
|
|
findAllSubKeys(hkey,0,0,keyname,&klist);
|
|
|
|
if (klist.next) {
|
|
pkl = klist.next;
|
|
|
|
while (pkl) {
|
|
RegCloseKey(pkl->subKey);
|
|
cr = RegDeleteKey(pkl->mainKey,pkl->keyname);
|
|
delete pkl->keyname;
|
|
k = pkl;
|
|
pkl = pkl->next;
|
|
delete k;
|
|
}
|
|
rc = 0;
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|