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