asiolist.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. #include <WinSock2.h>
  2. #include <Windows.h>
  3. #include "iasiodrv.h"
  4. #include "asiolist.h"
  5. #define ASIODRV_DESC "description"
  6. #define INPROC_SERVER "InprocServer32"
  7. #define ASIO_PATH "software\\asio"
  8. #define COM_CLSID "clsid"
  9. // ******************************************************************
  10. // Local Functions
  11. // ******************************************************************
  12. static LONG findDrvPath (char *clsidstr,char *dllpath,int dllpathsize)
  13. {
  14. HKEY hkEnum,hksub,hkpath;
  15. char databuf[512];
  16. LONG cr,rc = -1;
  17. DWORD datatype,datasize;
  18. DWORD index;
  19. OFSTRUCT ofs;
  20. HFILE hfile;
  21. BOOL found = FALSE;
  22. #ifdef UNICODE
  23. CharLowerBuffA(clsidstr,strlen(clsidstr));
  24. if ((cr = RegOpenKeyA(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) {
  25. index = 0;
  26. while (cr == ERROR_SUCCESS && !found) {
  27. cr = RegEnumKeyA(hkEnum,index++,databuf,512);
  28. if (cr == ERROR_SUCCESS) {
  29. CharLowerBuffA(databuf,strlen(databuf));
  30. if (!(strcmp(databuf,clsidstr))) {
  31. if ((cr = RegOpenKeyExA(hkEnum,databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
  32. if ((cr = RegOpenKeyExA(hksub,INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) {
  33. datatype = REG_SZ; datasize = (DWORD)dllpathsize;
  34. cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize);
  35. if (cr == ERROR_SUCCESS) {
  36. memset(&ofs,0,sizeof(OFSTRUCT));
  37. ofs.cBytes = sizeof(OFSTRUCT);
  38. hfile = OpenFile(dllpath,&ofs,OF_EXIST);
  39. if (hfile) rc = 0;
  40. }
  41. RegCloseKey(hkpath);
  42. }
  43. RegCloseKey(hksub);
  44. }
  45. found = TRUE; // break out
  46. }
  47. }
  48. }
  49. RegCloseKey(hkEnum);
  50. }
  51. #else
  52. CharLowerBuff(clsidstr,strlen(clsidstr));
  53. if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) {
  54. index = 0;
  55. while (cr == ERROR_SUCCESS && !found) {
  56. cr = RegEnumKey(hkEnum,index++,databuf,512);
  57. if (cr == ERROR_SUCCESS) {
  58. CharLowerBuff(databuf,strlen(databuf));
  59. if (!(strcmp(databuf,clsidstr))) {
  60. if ((cr = RegOpenKeyEx(hkEnum,databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
  61. if ((cr = RegOpenKeyEx(hksub,INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) {
  62. datatype = REG_SZ; datasize = (DWORD)dllpathsize;
  63. cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize);
  64. if (cr == ERROR_SUCCESS) {
  65. memset(&ofs,0,sizeof(OFSTRUCT));
  66. ofs.cBytes = sizeof(OFSTRUCT);
  67. hfile = OpenFile(dllpath,&ofs,OF_EXIST);
  68. if (hfile) rc = 0;
  69. }
  70. RegCloseKey(hkpath);
  71. }
  72. RegCloseKey(hksub);
  73. }
  74. found = TRUE; // break out
  75. }
  76. }
  77. }
  78. RegCloseKey(hkEnum);
  79. }
  80. #endif
  81. return rc;
  82. }
  83. static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv)
  84. {
  85. HKEY hksub;
  86. char databuf[256];
  87. char dllpath[MAXPATHLEN];
  88. WORD wData[100];
  89. CLSID clsid;
  90. DWORD datatype,datasize;
  91. LONG cr,rc;
  92. if (!lpdrv) {
  93. if ((cr = RegOpenKeyExA(hkey,keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
  94. datatype = REG_SZ; datasize = 256;
  95. cr = RegQueryValueExA(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize);
  96. if (cr == ERROR_SUCCESS) {
  97. rc = findDrvPath (databuf,dllpath,MAXPATHLEN);
  98. if (rc == 0) {
  99. lpdrv = new ASIODRVSTRUCT[1];
  100. if (lpdrv) {
  101. memset(lpdrv,0,sizeof(ASIODRVSTRUCT));
  102. lpdrv->drvID = drvID;
  103. MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100);
  104. if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) {
  105. memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID));
  106. }
  107. datatype = REG_SZ; datasize = 256;
  108. cr = RegQueryValueExA(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize);
  109. if (cr == ERROR_SUCCESS) {
  110. strcpy(lpdrv->drvname,databuf);
  111. }
  112. else strcpy(lpdrv->drvname,keyname);
  113. }
  114. }
  115. }
  116. RegCloseKey(hksub);
  117. }
  118. }
  119. else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next);
  120. return lpdrv;
  121. }
  122. static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv)
  123. {
  124. IASIO *iasio;
  125. if (lpdrv != 0) {
  126. deleteDrvStruct(lpdrv->next);
  127. if (lpdrv->asiodrv) {
  128. iasio = (IASIO *)lpdrv->asiodrv;
  129. iasio->Release();
  130. }
  131. delete lpdrv;
  132. }
  133. }
  134. static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv)
  135. {
  136. while (lpdrv) {
  137. if (lpdrv->drvID == drvID) return lpdrv;
  138. lpdrv = lpdrv->next;
  139. }
  140. return 0;
  141. }
  142. // ******************************************************************
  143. // ******************************************************************
  144. // AsioDriverList
  145. // ******************************************************************
  146. AsioDriverList::AsioDriverList ()
  147. {
  148. HKEY hkEnum = 0;
  149. char keyname[MAXDRVNAMELEN];
  150. LPASIODRVSTRUCT pdl;
  151. LONG cr;
  152. DWORD index = 0;
  153. BOOL fin = FALSE;
  154. numdrv = 0;
  155. lpdrvlist = 0;
  156. #ifdef UNICODE
  157. cr = RegOpenKeyA(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum);
  158. #else
  159. cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum);
  160. #endif
  161. while (cr == ERROR_SUCCESS) {
  162. #ifdef UNICODE
  163. if ((cr = RegEnumKeyA(hkEnum,index++,keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) {
  164. #else
  165. if ((cr = RegEnumKey(hkEnum,index++,keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) {
  166. #endif
  167. lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist);
  168. }
  169. else fin = TRUE;
  170. }
  171. if (hkEnum) RegCloseKey(hkEnum);
  172. pdl = lpdrvlist;
  173. while (pdl) {
  174. numdrv++;
  175. pdl = pdl->next;
  176. }
  177. if (numdrv) CoInitialize(0); // initialize COM
  178. }
  179. AsioDriverList::~AsioDriverList ()
  180. {
  181. if (numdrv) {
  182. deleteDrvStruct(lpdrvlist);
  183. CoUninitialize();
  184. }
  185. }
  186. LONG AsioDriverList::asioGetNumDev (VOID)
  187. {
  188. return (LONG)numdrv;
  189. }
  190. LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv)
  191. {
  192. LPASIODRVSTRUCT lpdrv = 0;
  193. long rc;
  194. if (!asiodrv) return DRVERR_INVALID_PARAM;
  195. if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
  196. if (!lpdrv->asiodrv) {
  197. rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv);
  198. if (rc == S_OK) {
  199. lpdrv->asiodrv = *asiodrv;
  200. return 0;
  201. }
  202. // else if (rc == REGDB_E_CLASSNOTREG)
  203. // strcpy (info->messageText, "Driver not registered in the Registration Database!");
  204. }
  205. else rc = DRVERR_DEVICE_ALREADY_OPEN;
  206. }
  207. else rc = DRVERR_DEVICE_NOT_FOUND;
  208. return rc;
  209. }
  210. LONG AsioDriverList::asioCloseDriver (int drvID)
  211. {
  212. LPASIODRVSTRUCT lpdrv = 0;
  213. IASIO *iasio;
  214. if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
  215. if (lpdrv->asiodrv) {
  216. iasio = (IASIO *)lpdrv->asiodrv;
  217. iasio->Release();
  218. lpdrv->asiodrv = 0;
  219. }
  220. }
  221. return 0;
  222. }
  223. LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize)
  224. {
  225. LPASIODRVSTRUCT lpdrv = 0;
  226. if (!drvname) return DRVERR_INVALID_PARAM;
  227. if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
  228. if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) {
  229. strcpy(drvname,lpdrv->drvname);
  230. }
  231. else {
  232. memcpy(drvname,lpdrv->drvname,drvnamesize-4);
  233. drvname[drvnamesize-4] = '.';
  234. drvname[drvnamesize-3] = '.';
  235. drvname[drvnamesize-2] = '.';
  236. drvname[drvnamesize-1] = 0;
  237. }
  238. return 0;
  239. }
  240. return DRVERR_DEVICE_NOT_FOUND;
  241. }
  242. LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize)
  243. {
  244. LPASIODRVSTRUCT lpdrv = 0;
  245. if (!dllpath) return DRVERR_INVALID_PARAM;
  246. if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
  247. if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) {
  248. strcpy(dllpath,lpdrv->dllpath);
  249. return 0;
  250. }
  251. dllpath[0] = 0;
  252. return DRVERR_INVALID_PARAM;
  253. }
  254. return DRVERR_DEVICE_NOT_FOUND;
  255. }
  256. LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid)
  257. {
  258. LPASIODRVSTRUCT lpdrv = 0;
  259. if (!clsid) return DRVERR_INVALID_PARAM;
  260. if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
  261. memcpy(clsid,&lpdrv->clsid,sizeof(CLSID));
  262. return 0;
  263. }
  264. return DRVERR_DEVICE_NOT_FOUND;
  265. }