#include #include 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\ sprintf(szregpath,"%s\\%s",SZREGSTR_SOFTWARE,SZREGSTR_ASIO); createRegPath (HKEY_LOCAL_MACHINE,szregpath,szregname); // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\ -> CLSID // HKEY_LOCAL_MACHINE\SOFTWARE\ASIO\ -> 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; }