[WHOAMI]
[reactos.git] / reactos / drivers / wdm / audio / drivers / CMIDriver / cmicontrol / main.cpp
1 /*
2 Copyright (c) 2006-2008 dogbert <dogber1@gmail.com>
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "main.h"
29
30
31 void PrintLastError(LPCSTR function)
32 {
33 LPVOID lpMsgBuf;
34 DWORD errorid = GetLastError();
35
36 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorid, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );
37 MessageBox(NULL, (LPCSTR)lpMsgBuf, function, MB_ICONEXCLAMATION | MB_OK);
38 LocalFree(lpMsgBuf);
39 }
40
41 BOOL generateTestSignal(double amplitude, int Channels, int SamplesPerSec, SHORT** buffer)
42 {
43 int i, o2, o3, o4, o5;
44 bool Left,Right,BackLeft,BackRight,Center,Sub, CenterLeft, CenterRight;
45 short value;
46 double x = SPEAKER_FREQUENCY*2*3.141592654/SamplesPerSec;
47 double y = BASS_FREQUENCY*2*3.141592654/SamplesPerSec;
48
49 Left = (SendMessage(GetDlgItem(hWndChild[0], IDC_LEFT), BM_GETCHECK, 0, 0) == BST_CHECKED);
50 Right = (SendMessage(GetDlgItem(hWndChild[0], IDC_RIGHT), BM_GETCHECK, 0, 0) == BST_CHECKED);
51 BackLeft = (SendMessage(GetDlgItem(hWndChild[0], IDC_BLEFT), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 2);
52 BackRight = (SendMessage(GetDlgItem(hWndChild[0], IDC_BRIGHT), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 2);
53 Center = (SendMessage(GetDlgItem(hWndChild[0], IDC_CENTER), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 4);
54 Sub = (SendMessage(GetDlgItem(hWndChild[0], IDC_SUB), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 4);
55 CenterLeft = (SendMessage(GetDlgItem(hWndChild[0], IDC_CLEFT), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 6);
56 CenterRight = (SendMessage(GetDlgItem(hWndChild[0], IDC_CRIGHT), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 6);
57
58 if (!(Left || Right || BackLeft || BackRight || Center || Sub || CenterLeft || CenterRight)) {
59 return FALSE;
60 }
61
62 if (currentChannelCount > 4) {
63 o2 = 4; o3 = 5;
64 o4 = 2; o5 = 3;
65 } else {
66 o2 = 2; o3 = 3;
67 o4 = 4; o5 = 5;
68 }
69
70 (*buffer) = (SHORT*)LocalAlloc(LPTR, SamplesPerSec*sizeof(SHORT)*Channels);
71 ZeroMemory((*buffer), SamplesPerSec*sizeof(SHORT)*Channels);
72
73 for (i=0;i<SamplesPerSec;i++) {
74 value = (SHORT)(cos(i*x)*amplitude*32767.0);
75 if (Left) {
76 (*buffer)[(i*Channels)+0] = value;
77 }
78 if (Right) {
79 (*buffer)[(i*Channels)+1] = value;
80 }
81 if (BackLeft) {
82 (*buffer)[(i*Channels)+o2] = value;
83 }
84 if (BackRight) {
85 (*buffer)[(i*Channels)+o3] = value;
86 }
87 if (Center) {
88 (*buffer)[(i*Channels)+o4] = value;
89 }
90 if (Sub) {
91 (*buffer)[(i*Channels)+o5] = (SHORT)(cos(i*y)*amplitude*32767.0);
92 }
93 if (CenterLeft) {
94 (*buffer)[(i*Channels)+6] = value;
95 }
96 if (CenterRight) {
97 (*buffer)[(i*Channels)+7] = value;
98 }
99 }
100 return TRUE;
101 }
102
103 BOOL stopTestTone(void)
104 {
105 if (hWave == NULL) {
106 return FALSE;
107 }
108
109 if (waveOutReset(hWave) != MMSYSERR_NOERROR) {
110 PrintLastError("waveOutReset()");
111 return FALSE;
112 }
113 if (waveOutClose(hWave) != MMSYSERR_NOERROR) {
114 PrintLastError("waveOutClose()");
115 return FALSE;
116 }
117 hWave = NULL;
118 LocalFree(pwh.lpData);
119 return TRUE;
120 }
121
122 UINT findWaveDeviceID()
123 {
124 WAVEOUTCAPS woc;
125 UINT i, numDev;
126
127 numDev = waveOutGetNumDevs();
128 for (i=0;i<numDev;i++) {
129 if (!waveOutGetDevCaps(i, &woc, sizeof(WAVEOUTCAPS))) {
130 if ((CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), NORM_IGNORECASE, woc.szPname, -1, TEXT("CMI8738/8768 Wave"), -1) == CSTR_EQUAL) ||
131 (CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), NORM_IGNORECASE, woc.szPname, -1, TEXT("Speakers (CMI8738/8768 Audio De"), -1) == CSTR_EQUAL)) {
132 return i;
133 }
134 }
135 }
136 return WAVE_MAPPER;
137 }
138
139 BOOL playTestTone()
140 {
141 SHORT* buffer;
142 BOOL isChannelChecked;
143 #if 1
144 WAVEFORMATEXTENSIBLE wfx;
145
146 ZeroMemory(&wfx, sizeof(WAVEFORMATEXTENSIBLE));
147 wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
148 wfx.Format.nChannels = (WORD)currentChannelCount;
149 wfx.Format.nSamplesPerSec = SAMPLE_RATE;
150 wfx.Format.wBitsPerSample = 16;
151 wfx.Format.nBlockAlign = (wfx.Format.wBitsPerSample >> 3) * wfx.Format.nChannels;
152 wfx.Format.nAvgBytesPerSec = SAMPLE_RATE * (wfx.Format.wBitsPerSample >> 3) * wfx.Format.nChannels;
153 wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
154 wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample ;
155 wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
156 #else
157 WAVEFORMATEX wfx;
158 wfx.wFormatTag = WAVE_FORMAT_PCM;
159 wfx.wBitsPerSample = 16;
160 wfx.nChannels = (WORD)currentChannelCount;
161 wfx.nSamplesPerSec = SAMPLE_RATE;
162 wfx.nAvgBytesPerSec = SAMPLE_RATE * (wfx.wBitsPerSample >> 3) * wfx.nChannels;
163 wfx.nBlockAlign = (wfx.wBitsPerSample >> 3) * wfx.nChannels;
164 wfx.cbSize = 0;
165 #endif
166
167 isChannelChecked = (SendMessage(GetDlgItem(hWndChild[0], IDC_LEFT), BM_GETCHECK, 0, 0) == BST_CHECKED);
168 isChannelChecked |= (SendMessage(GetDlgItem(hWndChild[0], IDC_RIGHT), BM_GETCHECK, 0, 0) == BST_CHECKED);
169 isChannelChecked |= (SendMessage(GetDlgItem(hWndChild[0], IDC_BLEFT), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 2);
170 isChannelChecked |= (SendMessage(GetDlgItem(hWndChild[0], IDC_BRIGHT), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 2);
171 isChannelChecked |= (SendMessage(GetDlgItem(hWndChild[0], IDC_CENTER), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 4);
172 isChannelChecked |= (SendMessage(GetDlgItem(hWndChild[0], IDC_SUB), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 4);
173 isChannelChecked |= (SendMessage(GetDlgItem(hWndChild[0], IDC_CLEFT), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 6);
174 isChannelChecked |= (SendMessage(GetDlgItem(hWndChild[0], IDC_CRIGHT), BM_GETCHECK, 0, 0) == BST_CHECKED) && (currentChannelCount > 6);
175
176 if (!isChannelChecked)
177 return FALSE;
178
179 if (waveOutOpen(&hWave, findWaveDeviceID(), (WAVEFORMATEX*)&(wfx), 0, 0, CALLBACK_NULL) != MMSYSERR_NOERROR) {
180 PrintLastError("waveOutOpen()");
181 return FALSE;
182 }
183
184 if (!generateTestSignal(SPEAKER_AMPLITUDE, currentChannelCount, SAMPLE_RATE, &buffer)) {
185 return FALSE;
186 }
187
188 ZeroMemory(&pwh, sizeof(pwh));
189 pwh.lpData = (LPSTR)buffer;
190 pwh.dwBufferLength = SAMPLE_RATE*sizeof(SHORT)*currentChannelCount;
191 pwh.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
192 pwh.dwLoops = 0xFFFFFFFF;
193 if (waveOutPrepareHeader(hWave, &pwh, sizeof(pwh)) != MMSYSERR_NOERROR) {
194 LocalFree(buffer);
195 PrintLastError("waveOutPrepareHeader()");
196 return FALSE;
197 }
198
199 if (waveOutReset(hWave) != MMSYSERR_NOERROR) {
200 LocalFree(buffer);
201 PrintLastError("waveOutReset()");
202 return FALSE;
203 }
204 if (waveOutWrite(hWave, &pwh, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
205 LocalFree(buffer);
206 PrintLastError("waveOutWrite()");
207 return FALSE;
208 }
209
210 return TRUE;
211 }
212
213
214 BOOL CALLBACK DSEnumProc(LPGUID lpGUID, LPCTSTR lpszDesc, LPCTSTR lpszDrvName, LPVOID lpContext)
215 {
216 LPGUID* pGUID = (LPGUID*)lpContext;
217
218 if (pGUID == NULL) {
219 return FALSE;
220 }
221 if ((*pGUID) != NULL) {
222 return TRUE;
223 }
224
225 if (lpGUID != NULL) {
226 // XP, 2k
227 if ((CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), NORM_IGNORECASE, lpszDrvName, -1, TEXT("cmipci.sys"), -1) == CSTR_EQUAL) &&
228 (CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), NORM_IGNORECASE, lpszDesc, -1, TEXT("CMI8738/8768 Wave"), -1) == CSTR_EQUAL)) {
229 (*pGUID) = (LPGUID)LocalAlloc(LPTR, sizeof(GUID));
230 memcpy((*pGUID), lpGUID, sizeof(GUID));
231 return TRUE;
232 }
233 // Vista
234 if (CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), NORM_IGNORECASE, lpszDesc, -1, TEXT("Speakers (CMI8738/8768 Audio Device)"), -1) == CSTR_EQUAL) {
235 (*pGUID) = (LPGUID)LocalAlloc(LPTR, sizeof(GUID));
236 memcpy((*pGUID), lpGUID, sizeof(GUID));
237 return TRUE;
238 }
239 }
240 return TRUE;
241 }
242
243 BOOL getCurrentChannelConfig()
244 {
245 IDirectSound8* ds;
246 DWORD speakerConfig;
247 LPGUID guid = NULL;
248
249 DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc, (VOID*)&guid);
250
251 if (DirectSoundCreate8(guid, &ds, NULL) != S_OK) {
252 return FALSE;
253 }
254
255 ds->Initialize(NULL);
256
257 if (ds->GetSpeakerConfig(&speakerConfig) != S_OK) {
258 PrintLastError("GetSpeakerConfig()");
259 return FALSE;
260 }
261
262 if (ds) {
263 ds->Release();
264 }
265 if (guid) {
266 LocalFree(guid);
267 }
268
269 switch (DSSPEAKER_CONFIG(speakerConfig)) {
270 case DSSPEAKER_STEREO: currentChannelCount = 2; return TRUE;
271 case DSSPEAKER_QUAD: currentChannelCount = 4; return TRUE;
272 case DSSPEAKER_5POINT1: currentChannelCount = 6; return TRUE;
273 case DSSPEAKER_7POINT1: currentChannelCount = 8; return TRUE;
274 }
275
276 return FALSE;
277 }
278
279 BOOL setCurrentChannelConfig()
280 {
281 IDirectSound8* ds;
282 DWORD speakerConfig;
283 LPGUID guid = NULL;
284
285 DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc, (VOID*)&guid);
286
287 if (DirectSoundCreate8(guid, &ds, NULL) != S_OK) {
288 PrintLastError("DirectSoundCreate8()");
289 return FALSE;
290 }
291
292
293 ds->Initialize(NULL);
294
295 switch (currentChannelCount) {
296 case 2: speakerConfig = DSSPEAKER_STEREO; break;
297 case 4: speakerConfig = DSSPEAKER_QUAD; break;
298 case 6: speakerConfig = DSSPEAKER_5POINT1; break;
299 case 8: speakerConfig = DSSPEAKER_7POINT1; break;
300 default: speakerConfig = DSSPEAKER_STEREO; break;
301 }
302
303 if (ds->SetSpeakerConfig(speakerConfig) != S_OK) {
304 PrintLastError("SetSpeakerConfig()");
305 return FALSE;
306 }
307
308 if (ds) {
309 ds->Release();
310 }
311 if (guid) {
312 LocalFree(guid);
313 }
314
315
316 return FALSE;
317 }
318
319 BOOL getDeviceInfo(const GUID* category, CMIDEV* pDev)
320 {
321 TCHAR szServiceName[128];
322 int nIndex = 0;
323
324 pDev->Info = SetupDiGetClassDevs(category, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
325 if (pDev->Info == INVALID_HANDLE_VALUE) {
326 PrintLastError("SetupDiGetClassDevs()");
327 return FALSE;
328 }
329
330 pDev->InfoData.cbSize = sizeof(SP_DEVINFO_DATA);
331
332 while (SetupDiEnumDeviceInfo(pDev->Info, nIndex, &(pDev->InfoData))) {
333 if (!SetupDiGetDeviceRegistryProperty(pDev->Info, &(pDev->InfoData), SPDRP_SERVICE, NULL, (PBYTE)szServiceName, sizeof(szServiceName), NULL)) {
334 PrintLastError("SetupDiGetDeviceRegistryProperty()");
335 SetupDiDestroyDeviceInfoList(pDev->Info);
336 pDev->Info = NULL;
337 return FALSE;
338 }
339
340 if (CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), NORM_IGNORECASE, szServiceName, -1, TEXT("cmipci"), -1) == CSTR_EQUAL) {
341 return TRUE;
342 }
343 nIndex++;
344 }
345
346 SetupDiDestroyDeviceInfoList(pDev->Info);
347 pDev->Info = NULL;
348 return FALSE;
349 }
350
351 BOOL getDeviceInterfaceDetail(const GUID* category, CMIDEV* pDev)
352 {
353 DWORD dataSize = 0;
354 BOOL result;
355 PTSTR pnpStr = NULL;
356 HDEVINFO hDevInfoWithInterface;
357 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
358
359 // get the PnP string
360 SetupDiGetDeviceInstanceId(pDev->Info, &(pDev->InfoData), NULL, 0, &dataSize);
361 if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (!dataSize)) {
362 PrintLastError("SetupDiGetDeviceInstanceId()");
363 return FALSE;
364 }
365 pnpStr = (PTSTR)LocalAlloc(LPTR, dataSize * sizeof(TCHAR));
366 if (!pnpStr) {
367 PrintLastError("LocalAlloc()");
368 return FALSE;
369 }
370 result = SetupDiGetDeviceInstanceId(pDev->Info, &(pDev->InfoData), pnpStr, dataSize, NULL);
371 if (!result) {
372 PrintLastError("SetupDiGetDeviceInstanceId()");
373 LocalFree(pnpStr);
374 return FALSE;
375 }
376 hDevInfoWithInterface = SetupDiGetClassDevs(&KSCATEGORY_TOPOLOGY, pnpStr, NULL, DIGCF_DEVICEINTERFACE);
377 LocalFree(pnpStr);
378 if (hDevInfoWithInterface == INVALID_HANDLE_VALUE) {
379 PrintLastError("SetupDiGetClassDevs()");
380 return FALSE;
381 }
382
383 // get the device interface data
384 DeviceInterfaceData.cbSize = sizeof(DeviceInterfaceData);
385 result = SetupDiEnumDeviceInterfaces(hDevInfoWithInterface, NULL, &KSCATEGORY_TOPOLOGY, 0, &DeviceInterfaceData);
386 if (!result) {
387 PrintLastError("SetupDiEnumDeviceInterfaces()");
388 SetupDiDestroyDeviceInfoList(hDevInfoWithInterface);
389 return FALSE;
390 }
391
392 // get the device interface detail data
393 dataSize = 0;
394 SetupDiGetDeviceInterfaceDetail(hDevInfoWithInterface, &DeviceInterfaceData, NULL, 0, &dataSize, NULL);
395 if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (!dataSize)) {
396 PrintLastError("SetupDiGetDeviceInterfaceDetail()");
397 SetupDiDestroyDeviceInfoList(hDevInfoWithInterface);
398 return FALSE;
399 }
400 pDev->InterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, dataSize);
401 if (!pDev->InterfaceDetailData) {
402 PrintLastError("LocalAlloc()");
403 SetupDiDestroyDeviceInfoList(hDevInfoWithInterface);
404 return FALSE;
405 }
406 pDev->InterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
407 result = SetupDiGetDeviceInterfaceDetail(hDevInfoWithInterface, &DeviceInterfaceData, pDev->InterfaceDetailData, dataSize, NULL, NULL);
408 SetupDiDestroyDeviceInfoList(hDevInfoWithInterface);
409 if (!result) {
410 PrintLastError("SetupDiGetDeviceInterfaceDetail()");
411 LocalFree(pDev->InterfaceDetailData);
412 pDev->InterfaceDetailData = NULL;
413 return FALSE;
414 }
415
416 return TRUE;
417
418 }
419
420 BOOL getDriverData(CMIDEV* pDev)
421 {
422 BOOL result;
423 HANDLE hDevice;
424 KSPROPERTY KSProp;
425 DWORD dataSize;
426
427 hDevice = CreateFile(pDev->InterfaceDetailData->DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
428 if (hDevice == INVALID_HANDLE_VALUE) {
429 PrintLastError("CreateFile()");
430 return FALSE;
431 }
432 KSProp.Set = KSPROPSETID_CMI;
433 KSProp.Flags = KSPROPERTY_TYPE_GET;
434 KSProp.Id = KSPROPERTY_CMI_GET;
435 result = DeviceIoControl(hDevice, IOCTL_KS_PROPERTY, &KSProp, sizeof(KSProp), &cmiData, sizeof(cmiData), &dataSize, NULL);
436 CloseHandle(hDevice);
437
438 if (!result) {
439 PrintLastError("DeviceIoControl()");
440 return FALSE;
441 }
442
443 return TRUE;
444 }
445
446 BOOL setDriverData(CMIDEV* pDev)
447 {
448 BOOL result;
449 HANDLE hDevice;
450 KSPROPERTY KSProp;
451 DWORD dataSize;
452
453 hDevice = CreateFile(pDev->InterfaceDetailData->DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
454 if (hDevice == INVALID_HANDLE_VALUE) {
455 PrintLastError("CreateFile()");
456 return FALSE;
457 }
458 KSProp.Set = KSPROPSETID_CMI;
459 KSProp.Flags = KSPROPERTY_TYPE_SET;
460 KSProp.Id = KSPROPERTY_CMI_SET;
461 result = DeviceIoControl(hDevice, IOCTL_KS_PROPERTY, &KSProp, sizeof(KSProp), &cmiData, sizeof(cmiData), &dataSize, NULL);
462 CloseHandle(hDevice);
463
464 if (!result) {
465 PrintLastError("DeviceIoControl()");
466 return FALSE;
467 }
468
469 return TRUE;
470 }
471
472 void cleanUp()
473 {
474 stopTestTone();
475 if (cmiTopologyDev.Info) {
476 SetupDiDestroyDeviceInfoList(cmiTopologyDev.Info);
477 cmiTopologyDev.Info = NULL;
478 }
479 if (cmiTopologyDev.InterfaceDetailData) {
480 LocalFree(cmiTopologyDev.InterfaceDetailData);
481 cmiTopologyDev.InterfaceDetailData = NULL;
482 }
483 if (hURLFont) {
484 DeleteObject(hURLFont); //hm?
485 hURLFont = NULL;
486 }
487 }
488
489 BOOL openDevice(bool handleError)
490 {
491 if (!getDeviceInfo(&KSCATEGORY_TOPOLOGY, &cmiTopologyDev)) {
492 if (handleError)
493 PrintLastError("getDeviceInfo()");
494 return FALSE;
495 }
496
497 if (!getDeviceInterfaceDetail(&KSCATEGORY_TOPOLOGY, &cmiTopologyDev)) {
498 if (handleError)
499 PrintLastError("getDeviceInterfaceDetail()");
500 return FALSE;
501 }
502
503 return TRUE;
504 }
505
506 void updateChannelBoxes(HWND hWnd)
507 {
508 switch (SendMessage(GetDlgItem(hWndChild[0], IDCB_CHANNELCONFIG), CB_GETCURSEL, 0, 0)) {
509 case 0: // stereo
510 ShowWindow(GetDlgItem(hWndChild[0], IDC_BLEFT), SW_HIDE);
511 ShowWindow(GetDlgItem(hWndChild[0], IDC_BRIGHT), SW_HIDE);
512 ShowWindow(GetDlgItem(hWndChild[0], IDC_CENTER), SW_HIDE);
513 ShowWindow(GetDlgItem(hWndChild[0], IDC_SUB), SW_HIDE);
514 ShowWindow(GetDlgItem(hWndChild[0], IDC_CLEFT), SW_HIDE);
515 ShowWindow(GetDlgItem(hWndChild[0], IDC_CRIGHT), SW_HIDE);
516 SetDlgItemText(hWnd, IDT_SWAPJACKS, "");
517 break;
518 case 1: // quad
519 ShowWindow(GetDlgItem(hWndChild[0], IDC_BLEFT), SW_SHOW);
520 ShowWindow(GetDlgItem(hWndChild[0], IDC_BRIGHT), SW_SHOW);
521 ShowWindow(GetDlgItem(hWndChild[0], IDC_CENTER), SW_HIDE);
522 ShowWindow(GetDlgItem(hWndChild[0], IDC_SUB), SW_HIDE);
523 ShowWindow(GetDlgItem(hWndChild[0], IDC_CLEFT), SW_HIDE);
524 ShowWindow(GetDlgItem(hWndChild[0], IDC_CRIGHT), SW_HIDE);
525 SetDlgItemText(hWnd, IDT_SWAPJACKS, "");
526 break;
527 case 2: // 5.1
528 ShowWindow(GetDlgItem(hWndChild[0], IDC_BLEFT), SW_SHOW);
529 ShowWindow(GetDlgItem(hWndChild[0], IDC_BRIGHT), SW_SHOW);
530 ShowWindow(GetDlgItem(hWndChild[0], IDC_CENTER), SW_SHOW);
531 ShowWindow(GetDlgItem(hWndChild[0], IDC_SUB), SW_SHOW);
532 ShowWindow(GetDlgItem(hWndChild[0], IDC_CLEFT), SW_HIDE);
533 ShowWindow(GetDlgItem(hWndChild[0], IDC_CRIGHT), SW_HIDE);
534 SetDlgItemText(hWnd, IDT_SWAPJACKS, "BL/BR and C/LFE jacks are swapped!");
535 break;
536 case 3: // 7.1
537 ShowWindow(GetDlgItem(hWndChild[0], IDC_BLEFT), SW_SHOW);
538 ShowWindow(GetDlgItem(hWndChild[0], IDC_BRIGHT), SW_SHOW);
539 ShowWindow(GetDlgItem(hWndChild[0], IDC_CENTER), SW_SHOW);
540 ShowWindow(GetDlgItem(hWndChild[0], IDC_SUB), SW_SHOW);
541 ShowWindow(GetDlgItem(hWndChild[0], IDC_CLEFT), SW_SHOW);
542 ShowWindow(GetDlgItem(hWndChild[0], IDC_CRIGHT), SW_SHOW);
543 SetDlgItemText(hWnd, IDT_SWAPJACKS, "BL/BR and C/LFE jacks are swapped!");
544 break;
545 }
546 }
547
548
549 BOOL setDlgItems(HWND hWnd)
550 {
551 HWND hWndItem;
552 char buffer[127];
553
554 if (!getDriverData(&cmiTopologyDev)) {
555 PrintLastError("getDriverData()");
556 return FALSE;
557 }
558
559 // 'About' tab
560 SetWindowText(GetDlgItem(hWndChild[NUM_TABS-1], IDC_VERSION), cmiData.driverVersion);
561 wsprintf(buffer, "%d", cmiData.hardwareRevision);
562 SetWindowText(GetDlgItem(hWndChild[NUM_TABS-1], IDC_HWREV), buffer);
563 wsprintf(buffer, "%d", cmiData.maxChannels);
564 SetWindowText(GetDlgItem(hWndChild[NUM_TABS-1], IDC_MAXCHAN), buffer);
565 wsprintf(buffer, "%04X", cmiData.IOBase);
566 SetWindowText(GetDlgItem(hWndChild[NUM_TABS-1], IDC_BASEADR), buffer);
567 wsprintf(buffer, "%04X", cmiData.MPUBase);
568 SetWindowText(GetDlgItem(hWndChild[NUM_TABS-1], IDC_MPUADR), buffer);
569
570 // channel config combobox
571 hWndItem = GetDlgItem(hWndChild[0], IDCB_CHANNELCONFIG);
572 SendMessage(hWndItem, CB_RESETCONTENT, 0, 0);
573 if (cmiData.maxChannels >= 2) {
574 SendMessage(hWndItem, CB_ADDSTRING, 0, (LPARAM)"Stereo (2.0)");
575 }
576 if (cmiData.maxChannels >= 4) {
577 SendMessage(hWndItem, CB_ADDSTRING, 0, (LPARAM)"Quadrophonic (4.0)");
578 }
579 if (cmiData.maxChannels >= 6) {
580 SendMessage(hWndItem, CB_ADDSTRING, 0, (LPARAM)"5.1 Surround");
581 }
582 if (cmiData.maxChannels >= 8) {
583 SendMessage(hWndItem, CB_ADDSTRING, 0, (LPARAM)"7.1 Surround");
584 }
585 if (getCurrentChannelConfig()) {
586 EnableWindow(GetDlgItem(hWndChild[0], IDB_STARTSTOP), TRUE);
587 EnableWindow(GetDlgItem(hWndChild[0], IDCB_CHANNELCONFIG), TRUE);
588 SendMessage(hWndItem, CB_SETCURSEL, (currentChannelCount/2)-1, 0);
589 updateChannelBoxes(hWnd);
590 } else {
591 EnableWindow(GetDlgItem(hWndChild[0], IDB_STARTSTOP), FALSE);
592 EnableWindow(GetDlgItem(hWndChild[0], IDCB_CHANNELCONFIG), FALSE);
593 }
594
595 // checkboxes
596 SendMessage(GetDlgItem(hWndChild[0], IDC_EXCH_FB), BM_SETCHECK, (cmiData.exchangeFrontBack ? BST_CHECKED : BST_UNCHECKED), 0);
597 SendMessage(GetDlgItem(hWndChild[0], IDC_EN_SPDIMONITOR), BM_SETCHECK, (cmiData.enableSPDIMonitor ? BST_CHECKED : BST_UNCHECKED), 0);
598
599 SendMessage(GetDlgItem(hWndChild[1], IDC_EN_SPDO), BM_SETCHECK, (cmiData.enableSPDO ? BST_CHECKED : BST_UNCHECKED), 0);
600 SendMessage(GetDlgItem(hWndChild[1], IDC_EN_SPDO5V), BM_SETCHECK, (cmiData.enableSPDO5V ? BST_CHECKED : BST_UNCHECKED), 0);
601 SendMessage(GetDlgItem(hWndChild[1], IDC_EN_SPDCOPYRHT), BM_SETCHECK, (cmiData.enableSPDOCopyright ? BST_CHECKED : BST_UNCHECKED), 0);
602 SendMessage(GetDlgItem(hWndChild[1], IDC_EN_SPDI), BM_SETCHECK, (cmiData.enableSPDI ? BST_CHECKED : BST_UNCHECKED), 0);
603 SendMessage(GetDlgItem(hWndChild[1], IDC_SEL_SPDIFI), BM_SETCHECK, (cmiData.select2ndSPDI ? BST_CHECKED : BST_UNCHECKED), 0);
604 SendMessage(GetDlgItem(hWndChild[1], IDC_INV_SPDIFI), BM_SETCHECK, (cmiData.invertPhaseSPDI ? BST_CHECKED : BST_UNCHECKED), 0);
605 SendMessage(GetDlgItem(hWndChild[1], IDC_POLVALID), BM_SETCHECK, (cmiData.invertValidBitSPDI ? BST_CHECKED : BST_UNCHECKED), 0);
606 SendMessage(GetDlgItem(hWndChild[1], IDC_LOOP_SPDF), BM_SETCHECK, (cmiData.loopSPDI ? BST_CHECKED : BST_UNCHECKED), 0);
607
608 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_441_PCM), BM_SETCHECK, ((cmiData.formatMask & FMT_441_PCM) ? BST_CHECKED : BST_UNCHECKED), 0);
609 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_480_PCM), BM_SETCHECK, ((cmiData.formatMask & FMT_480_PCM) ? BST_CHECKED : BST_UNCHECKED), 0);
610 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_882_PCM), BM_SETCHECK, ((cmiData.formatMask & FMT_882_PCM) ? BST_CHECKED : BST_UNCHECKED), 0);
611 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_960_PCM), BM_SETCHECK, ((cmiData.formatMask & FMT_960_PCM) ? BST_CHECKED : BST_UNCHECKED), 0);
612 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_441_MULTI_PCM),BM_SETCHECK, ((cmiData.formatMask & FMT_441_MULTI_PCM) ? BST_CHECKED : BST_UNCHECKED), 0);
613 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_480_MULTI_PCM),BM_SETCHECK, ((cmiData.formatMask & FMT_480_MULTI_PCM) ? BST_CHECKED : BST_UNCHECKED), 0);
614 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_882_MULTI_PCM),BM_SETCHECK, ((cmiData.formatMask & FMT_882_MULTI_PCM) ? BST_CHECKED : BST_UNCHECKED), 0);
615 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_960_MULTI_PCM),BM_SETCHECK, ((cmiData.formatMask & FMT_960_MULTI_PCM) ? BST_CHECKED : BST_UNCHECKED), 0);
616 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_441_DOLBY), BM_SETCHECK, ((cmiData.formatMask & FMT_441_DOLBY) ? BST_CHECKED : BST_UNCHECKED), 0);
617 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_480_DOLBY), BM_SETCHECK, ((cmiData.formatMask & FMT_480_DOLBY) ? BST_CHECKED : BST_UNCHECKED), 0);
618 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_882_DOLBY), BM_SETCHECK, ((cmiData.formatMask & FMT_882_DOLBY) ? BST_CHECKED : BST_UNCHECKED), 0);
619 SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_960_DOLBY), BM_SETCHECK, ((cmiData.formatMask & FMT_960_DOLBY) ? BST_CHECKED : BST_UNCHECKED), 0);
620
621 // radioboxes
622 SendMessage(GetDlgItem(hWndChild[0], IDC_EN_REAR2LINE), BM_SETCHECK, (cmiData.enableRear2Line ? BST_CHECKED : BST_UNCHECKED), 0);
623 SendMessage(GetDlgItem(hWndChild[0], IDC_EN_CLFE2LINE), BM_SETCHECK, ((cmiData.enableCenter2Line | cmiData.enableBass2Line) ? BST_CHECKED : BST_UNCHECKED), 0);
624 SendMessage(GetDlgItem(hWndChild[0], IDC_NOROUTE_LINE), BM_SETCHECK, ((!cmiData.enableCenter2Line && !cmiData.enableBass2Line && !cmiData.enableRear2Line) ? BST_CHECKED : BST_UNCHECKED), 0);
625
626 SendMessage(GetDlgItem(hWndChild[0], IDC_EN_CENTER2MIC), BM_SETCHECK, (cmiData.enableCenter2Mic ? BST_CHECKED : BST_UNCHECKED), 0);
627 SendMessage(GetDlgItem(hWndChild[0], IDC_NOROUTE_MIC), BM_SETCHECK, (!cmiData.enableCenter2Mic ? BST_CHECKED : BST_UNCHECKED), 0);
628
629
630 return TRUE;
631 }
632
633 BOOL applySettings()
634 {
635 cmiData.exchangeFrontBack = (SendMessage(GetDlgItem(hWndChild[0], IDC_EXCH_FB), BM_GETCHECK, 0, 0) == BST_CHECKED);
636 cmiData.enableBass2Line = (SendMessage(GetDlgItem(hWndChild[0], IDC_EN_CLFE2LINE), BM_GETCHECK, 0, 0) == BST_CHECKED);
637 cmiData.enableCenter2Line = (SendMessage(GetDlgItem(hWndChild[0], IDC_EN_CLFE2LINE), BM_GETCHECK, 0, 0) == BST_CHECKED);
638 cmiData.enableRear2Line = (SendMessage(GetDlgItem(hWndChild[0], IDC_EN_REAR2LINE), BM_GETCHECK, 0, 0) == BST_CHECKED);
639 cmiData.enableCenter2Mic = (SendMessage(GetDlgItem(hWndChild[0], IDC_EN_CENTER2MIC), BM_GETCHECK, 0, 0) == BST_CHECKED);
640 cmiData.enableSPDIMonitor = (SendMessage(GetDlgItem(hWndChild[0], IDC_EN_SPDIMONITOR), BM_GETCHECK, 0, 0) == BST_CHECKED);
641
642 cmiData.enableSPDO = (SendMessage(GetDlgItem(hWndChild[1], IDC_EN_SPDO), BM_GETCHECK, 0, 0) == BST_CHECKED);
643 cmiData.enableSPDO5V = (SendMessage(GetDlgItem(hWndChild[1], IDC_EN_SPDO5V), BM_GETCHECK, 0, 0) == BST_CHECKED);
644 cmiData.enableSPDOCopyright = (SendMessage(GetDlgItem(hWndChild[1], IDC_EN_SPDCOPYRHT), BM_GETCHECK, 0, 0) == BST_CHECKED);
645 cmiData.enableSPDI = (SendMessage(GetDlgItem(hWndChild[1], IDC_EN_SPDI), BM_GETCHECK, 0, 0) == BST_CHECKED);
646 cmiData.select2ndSPDI = (SendMessage(GetDlgItem(hWndChild[1], IDC_SEL_SPDIFI), BM_GETCHECK, 0, 0) == BST_CHECKED);
647 cmiData.invertPhaseSPDI = (SendMessage(GetDlgItem(hWndChild[1], IDC_INV_SPDIFI), BM_GETCHECK, 0, 0) == BST_CHECKED);
648 cmiData.invertValidBitSPDI = (SendMessage(GetDlgItem(hWndChild[1], IDC_POLVALID), BM_GETCHECK, 0, 0) == BST_CHECKED);
649 cmiData.loopSPDI = (SendMessage(GetDlgItem(hWndChild[1], IDC_LOOP_SPDF), BM_GETCHECK, 0, 0) == BST_CHECKED);
650
651 cmiData.formatMask = 0;
652 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_441_PCM), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_441_PCM : 0;
653 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_480_PCM), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_480_PCM : 0;
654 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_882_PCM), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_882_PCM : 0;
655 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_960_PCM), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_960_PCM : 0;
656 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_441_MULTI_PCM), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_441_MULTI_PCM : 0;
657 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_480_MULTI_PCM), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_480_MULTI_PCM : 0;
658 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_882_MULTI_PCM), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_882_MULTI_PCM : 0;
659 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_960_MULTI_PCM), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_960_MULTI_PCM : 0;
660 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_441_DOLBY), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_441_DOLBY : 0;
661 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_480_DOLBY), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_480_DOLBY : 0;
662 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_882_DOLBY), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_882_DOLBY : 0;
663 cmiData.formatMask |= (SendMessage(GetDlgItem(hWndChild[2], IDC_FMT_960_DOLBY), BM_GETCHECK, 0, 0) == BST_CHECKED) ? FMT_960_DOLBY : 0;
664
665 currentChannelCount = (int)(SendMessage(GetDlgItem(hWndChild[0], IDCB_CHANNELCONFIG), CB_GETCURSEL, 0, 0)+1)*2;
666
667 return (setDriverData(&cmiTopologyDev) && setCurrentChannelConfig());
668 }
669
670 BOOL initDialog(HWND hWnd)
671 {
672 HICON hIcon;
673 TC_ITEM tci;
674 int i;
675
676 hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_APP_ICON));
677 SendMessage(hWnd, WM_SETICON, (LPARAM) ICON_BIG, (WPARAM) hIcon);
678 hURLFont = 0;
679
680 hWndTab = GetDlgItem(hWnd,IDC_TAB);
681
682 ZeroMemory(&tci, sizeof(TC_ITEM));
683 tci.mask = TCIF_TEXT;
684 for (i=0;i<NUM_TABS;i++) {
685 tci.pszText = tabsName[i];
686 if (TabCtrl_InsertItem(hWndTab, i, &tci) == -1) {
687 PrintLastError("TabCtrl_InsertItem()");
688 return FALSE;
689 }
690 hWndChild[i] = CreateDialogParam(hInst, MAKEINTRESOURCE(tabsResource[i]), hWndTab, (DLGPROC)TabDlgProc, 0);
691 }
692
693 hURLFont = CreateFont(20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VARIABLE_PITCH | FF_SWISS, "MS Shell Dlg");
694 SendMessage(GetDlgItem(hWndChild[NUM_TABS-1], IDC_URL2), WM_SETFONT, (WPARAM)hURLFont, TRUE);
695
696 currentTab = 0;
697 ShowWindow(hWndChild[0], SW_SHOWDEFAULT);
698
699 if (!openDevice(TRUE)) {
700 PrintLastError("openDevice()");
701 return FALSE;
702 }
703 return setDlgItems(hWnd);
704 }
705
706 BOOL changeTab(LPNMHDR lpnmhdr)
707 {
708 if (lpnmhdr->code != TCN_SELCHANGE) {
709 return FALSE;
710 }
711 ShowWindow(hWndChild[currentTab], SW_HIDE);
712 currentTab = SendMessage(hWndTab, TCM_GETCURSEL, 0, 0);
713 ShowWindow(hWndChild[currentTab], SW_SHOWDEFAULT);
714 return TRUE;
715 }
716
717 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
718 {
719 switch(msg) {
720 case WM_INITDIALOG:
721 if (!initDialog(hWnd)) {
722 PostQuitMessage(0);
723 }
724 return TRUE;
725 case WM_CLOSE:
726 DestroyWindow(hWnd);
727 return TRUE;
728 case WM_NOTIFY:
729 return changeTab((LPNMHDR)lParam);
730 case WM_DESTROY:
731 cleanUp();
732 PostQuitMessage(0);
733 return TRUE;
734 case WM_COMMAND:
735 if (LOWORD(wParam) == IDB_CLOSE) {
736 PostQuitMessage(0);
737 return TRUE;
738 }
739 if (LOWORD(wParam) == IDB_APPLY) {
740 applySettings();
741 setDlgItems(hWnd);
742 return TRUE;
743 }
744 break;
745 }
746 return 0;
747 }
748
749 void openURL(int control)
750 {
751 char buffer[127];
752 GetWindowText(GetDlgItem(hWndChild[3], control), buffer, sizeof(buffer));
753 ShellExecute(hWndMain, "open", buffer, NULL, NULL, SW_SHOWNORMAL);
754 }
755
756 LRESULT CALLBACK TabDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
757 {
758 switch(msg) {
759 case WM_COMMAND:
760 switch (LOWORD(wParam)) {
761 case IDB_STARTSTOP:
762 if (stopTestTone()) {
763 SetDlgItemText(hWndChild[0], IDB_STARTSTOP, "&Play test tone");
764 return TRUE;
765 }
766 if (playTestTone()) {
767 SetDlgItemText(hWndChild[0], IDB_STARTSTOP, "&Stop");
768 return TRUE;
769 }
770 break;
771 case IDC_URL1:
772 case IDC_URL2:
773 openURL(LOWORD(wParam));
774 break;
775 }
776 case WM_CTLCOLORSTATIC:
777 if ( (GetDlgItem(hWndChild[3], IDC_URL1) == (HANDLE)lParam) || (GetDlgItem(hWndChild[3], IDC_URL2) == (HANDLE)lParam) ) {
778 SetTextColor((HDC)wParam, 0xFF0000);
779 SetBkMode((HDC)wParam, TRANSPARENT);
780 return (LRESULT)GetSysColorBrush(COLOR_BTNFACE);
781 }
782 }
783
784 return 0;
785 }
786
787 void printUsage()
788 {
789 unsigned char usage[] = "/h - print this help message\r\n" \
790 "/enable71Mode - change channel configuration to 7.1\r\n" \
791 "/enable51Mode - change channel configuration to 5.1\r\n" \
792 "/enable40Mode - change channel configuration to 4.0 (Quad)\r\n" \
793 "/enable20Mode - change channel configuration to 2.0 (Stereo)\r\n" \
794 "/enableSPDIFo - enable SPDIF-out\r\n" \
795 "/disableSPDIFo - disable SPDIF-out\r\n"\
796 "/enableSPDIFi - enable SPDIF-in recording\r\n" \
797 "/disableSPDIFi - disable SPDIF-in recording\r\n" \
798 "/enableLoopThru - enable loop-through from SPDIF-in to SPDIF-out\r\n" \
799 "/disableLoopThru - disable loop-through from SPDIF-in to SPDIF-out\r\n";
800
801 MessageBox(NULL, (LPCSTR)usage, TEXT("Usage Help"), MB_ICONINFORMATION | MB_OK);
802 return;
803 }
804
805 void deleteDriverFiles() {
806 TCHAR SysDir[MAX_PATH];
807 unsigned int len;
808 if (GetSystemDirectory(SysDir, sizeof(SysDir))==0) {
809 PrintLastError("GetSystemDirectory()");
810 return;
811 }
812 len = strlen(SysDir);
813
814 strcat(SysDir, "\\cmicpl.cpl");
815 if (!DeleteFile(SysDir)) {
816 MoveFileEx(SysDir, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
817 }
818 SysDir[len] = 0;
819
820 strcat(SysDir, "\\cmicontrol.exe");
821 if (!DeleteFile(SysDir)) {
822 MoveFileEx(SysDir, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
823 }
824 }
825
826
827 void performUninstall() {
828 deleteDriverFiles();
829 RegDeleteKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\CMIDriver");
830 MessageBox(NULL, "The CMI driver applications have been successfully removed from your computer!", "CMIDriver", MB_ICONINFORMATION);
831 ExitProcess(0);
832 }
833
834 bool checkToken(char* token) {
835 if ((strcmp(token, "?")==0) || (strcmp(token, "H")==0)) {
836 printUsage();
837 return TRUE;
838 } else
839 if (strcmp(token, "ENABLE71MODE")==0) {
840 currentChannelCount = 8;
841 } else
842 if (strcmp(token, "ENABLE51MODE")==0) {
843 currentChannelCount = 6;
844 } else
845 if ((strcmp(token, "ENABLE40MODE")==0) || (strcmp(token, "ENABLEQUADMODE")==0) || (strcmp(token, "QUAD")==0) ) {
846 currentChannelCount = 4;
847 } else
848 if ((strcmp(token, "ENABLE20MODE")==0) || (strcmp(token, "ENABLESTEREOMODE")==0) || (strcmp(token, "STEREO")==0) ) {
849 currentChannelCount = 2;
850 } else
851 if (strcmp(token, "ENABLESPDIFO")==0) {
852 cmiData.enableSPDO = TRUE;
853 } else
854 if (strcmp(token, "DISABLESPDIFO")==0) {
855 cmiData.enableSPDO = FALSE;
856 } else
857 if (strcmp(token, "ENABLESPDIFI")==0) {
858 cmiData.enableSPDI = TRUE;
859 } else
860 if (strcmp(token, "DISABLESPDIFI")==0) {
861 cmiData.enableSPDI = FALSE;
862 } else
863 if ((strcmp(token, "ENABLELOOPTHRU")==0) || (strcmp(token, "ENABLELOOPTHROUGH")==0) || (strcmp(token, "ENABLELOOP")==0) ) {
864 cmiData.loopSPDI = TRUE;
865 } else
866 if ((strcmp(token, "DISABLELOOPTHRU")==0) || (strcmp(token, "DISABLELOOPTHROUGH")==0) || (strcmp(token, "DISABLELOOP")==0) ) {
867 cmiData.loopSPDI = FALSE;
868 } else
869 if (strcmp(token, "UNINSTALL")==0) {
870 performUninstall();
871 }
872 return FALSE;
873 }
874
875 int parseArguments(LPSTR szCmdLine) {
876 BOOL inToken = false, result;
877 int i = 0, j=0;
878 char token[MAX_TOKEN_SIZE];
879
880 if (openDevice(FALSE)) {
881 getDriverData(&cmiTopologyDev);
882 currentChannelCount = -1;
883 }
884
885 while (szCmdLine[i]) {
886 if (inToken) {
887 if (szCmdLine[i] == ' ') {
888 inToken = false;
889 token[j] = 0;
890 if (checkToken(token)) {
891 return TRUE;
892 }
893 } else {
894 token[j] = (char)toupper(szCmdLine[i]);
895 if (j < MAX_TOKEN_SIZE-1) {
896 j++;
897 }
898 }
899 } else {
900 if ((szCmdLine[i] == '-') || (szCmdLine[i] == '/')) {
901 j = 0;
902 inToken = true;
903 }
904 }
905
906 i++;
907 }
908 token[j] = 0;
909 checkToken(token);
910
911 result = setDriverData(&cmiTopologyDev);
912 if (currentChannelCount != -1)
913 result |= setCurrentChannelConfig();
914 return result;
915 }
916
917 void InitURLControl()
918 {
919 WNDCLASSEX wce;
920
921 ZeroMemory(&wce, sizeof(wce));
922 wce.cbSize = sizeof(WNDCLASSEX);
923 if (GetClassInfoEx(hInst, "Static", &wce)==0) {
924 PrintLastError("GetClassInfoEx()");
925 return;
926 }
927
928 wce.hCursor = LoadCursor(NULL, IDC_HAND);
929 wce.hInstance = hInst;
930 wce.lpszClassName = "URLLink";
931 if (RegisterClassEx(&wce) == 0) {
932 PrintLastError("RegisterClassEx()");
933 }
934
935 }
936
937 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
938 {
939 WNDCLASSEX wce;
940 MSG msg;
941
942 ZeroMemory(&cmiData, sizeof(CMIDATA));
943 ZeroMemory(&cmiTopologyDev, sizeof(CMIDEV));
944 hWave = NULL;
945
946 if (szCmdLine && szCmdLine[0] != 0) {
947 int result = parseArguments(szCmdLine);
948 cleanUp();
949 return result;
950 }
951
952 if ((hWndMain = FindWindow("cmiControlPanel", NULL))) {
953 SetForegroundWindow(hWndMain);
954 return FALSE;
955 }
956
957 hInst = hInstance;
958 InitCommonControls();
959 CoInitialize(NULL);
960
961 ZeroMemory(&wce, sizeof(WNDCLASSEX));
962 wce.cbSize = sizeof(WNDCLASSEX);
963 wce.lpfnWndProc = DefDlgProc;
964 wce.style = 0;
965 wce.cbWndExtra = DLGWINDOWEXTRA;
966 wce.hInstance = hInstance;
967 wce.hCursor = LoadCursor(NULL, IDC_ARROW);
968 wce.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
969 wce.lpszClassName = "cmiControlPanel";
970 wce.lpszMenuName = NULL;
971 wce.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
972 wce.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
973 if(!RegisterClassEx(&wce)) {
974 PrintLastError("RegisterClassEx()");
975 return -1;
976 }
977 InitURLControl();
978
979 hWndMain = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, (DLGPROC)WndProc, NULL);
980 if (!hWndMain) {
981 PrintLastError("CreateDialogParam()");
982 return -1;
983 }
984
985 while (GetMessage(&msg, (HWND) NULL, 0, 0)) {
986 TranslateMessage(&msg);
987 DispatchMessage(&msg);
988 }
989 return 0;
990 }