Sync with trunk head (r48654)
[reactos.git] / base / applications / dxdiag / sound.c
1 /*
2 * PROJECT: ReactX Diagnosis Application
3 * LICENSE: LGPL - See COPYING in the top level directory
4 * FILE: base/applications/dxdiag/sound.c
5 * PURPOSE: ReactX diagnosis sound page
6 * COPYRIGHT: Copyright 2008 Johannes Anderwald
7 *
8 */
9
10 #include "precomp.h"
11 #include <devguid.h>
12 #include <dsound.h>
13
14 #if 0
15 BOOL
16 GetCatFileFromDriverPath(LPWSTR szFileName, LPWSTR szCatFileName)
17 {
18 GUID VerifyGuid = DRIVER_ACTION_VERIFY;
19 HANDLE hFile;
20 DWORD dwHash;
21 BYTE bHash[100];
22 HCATINFO hCatInfo;
23 HCATADMIN hActAdmin;
24 BOOL bRet = FALSE;
25 CATALOG_INFO CatInfo;
26
27 /* attempt to open file */
28 hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
29 if (hFile == INVALID_HANDLE_VALUE)
30 return FALSE;
31
32 /* calculate hash from file handle */
33 dwHash = sizeof(bHash);
34 if (!CryptCATAdminCalcHashFromFileHandle(hFile, &dwHash, bHash, 0))
35 {
36 CloseHandle(hFile);
37 return FALSE;
38 }
39
40 /* try open the CAT admin */
41 if (!CryptCATAdminAcquireContext(&hActAdmin, &VerifyGuid, 0))
42 {
43 CloseHandle(hFile);
44 return FALSE;
45 }
46
47 /* search catalog to find for catalog containing this hash */
48 hCatInfo = CryptCATAdminEnumCatalogFromHash(hActAdmin, bHash, dwHash, 0, NULL);
49 if (hCatInfo != NULL)
50 {
51 /* theres a catalog get the filename */
52 bRet = CryptCATCatalogInfoFromContext(hCatInfo, &CatInfo, 0);
53 if (bRet)
54 wcscpy(szCatFileName, CatInfo.wszCatalogFile);
55 CryptCATAdminReleaseCatalogContext(hActAdmin, hCatInfo, 0);
56 }
57
58 /* perform cleanup */
59 CloseHandle(hFile);
60 CryptCATAdminReleaseContext(hActAdmin, 0);
61 return bRet;
62 }
63
64 BOOL
65 IsDriverWHQL(LPWSTR szFileName)
66 {
67 WCHAR szCatFile[MAX_PATH];
68 HANDLE hCat;
69 BOOL bRet = FALSE;
70
71 /* get the driver's cat file */
72 if (!GetCatFileFromDriverPath(szFileName, szCatFile))
73 {
74 /* driver has no cat so its definately not WHQL signed */
75 return FALSE;
76 }
77
78 /* open the CAT file */
79 hCat = CryptCATOpen(szCatFile, CRYPTCAT_OPEN_EXISTING, 0, 0, 0);
80 if (hCat == INVALID_HANDLE_VALUE)
81 {
82 /* couldnt open cat */
83 return FALSE;
84 }
85
86 /* FIXME
87 * build certificate chain with CertGetCertificateChain
88 * verify certificate chain (WinVerifyTrust)
89 * retrieve signer (WTHelperGetProvSignerFromChain)
90 */
91
92
93 /* close CAT file */
94 CryptCATClose(hCat);
95 return bRet;
96 }
97 #endif
98
99 static
100 void
101 SetDeviceDetails(HWND hwndDlg, LPCGUID classGUID, LPCWSTR lpcstrDescription)
102 {
103 HDEVINFO hInfo;
104 DWORD dwIndex = 0;
105 SP_DEVINFO_DATA InfoData;
106 WCHAR szText[30];
107 HWND hDlgCtrls[3];
108 WAVEOUTCAPSW waveOut;
109 UINT numDev;
110 MMRESULT errCode;
111
112
113 /* enumerate waveout devices */
114 numDev = waveOutGetNumDevs();
115 if (numDev)
116 {
117 do
118 {
119 ZeroMemory(&waveOut, sizeof(waveOut));
120 errCode = waveOutGetDevCapsW(dwIndex++, &waveOut, sizeof(waveOut));
121 if (!wcsncmp(lpcstrDescription, waveOut.szPname, min(MAXPNAMELEN, wcslen(waveOut.szPname))))
122 {
123 /* set the product id */
124 SetDlgItemInt(hwndDlg, IDC_STATIC_DSOUND_PRODUCTID, waveOut.wPid, FALSE);
125 /* set the vendor id */
126 SetDlgItemInt(hwndDlg, IDC_STATIC_DSOUND_VENDORID, waveOut.wMid, FALSE);
127 /* check if its a wdm audio driver */
128 if (waveOut.wPid == MM_MSFT_WDMAUDIO_WAVEOUT)
129 SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_TYPE, WM_SETTEXT, 0, (LPARAM)L"WDM");
130
131 /* check if device is default device */
132 szText[0] = L'\0';
133 if (dwIndex - 1 == 0) /* FIXME assume default playback device is device 0 */
134 LoadStringW(hInst, IDS_OPTION_YES, szText, sizeof(szText)/sizeof(WCHAR));
135 else
136 LoadStringW(hInst, IDS_OPTION_NO, szText, sizeof(szText)/sizeof(WCHAR));
137
138 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
139 /* set default device info */
140 SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_STANDARD, WM_SETTEXT, 0, (LPARAM)szText);
141 break;
142 }
143 }while(errCode == MMSYSERR_NOERROR && dwIndex < numDev);
144 }
145
146 dwIndex = 0;
147 /* create the setup list */
148 hInfo = SetupDiGetClassDevsW(classGUID, NULL, NULL, DIGCF_PRESENT|DIGCF_PROFILE);
149 if (hInfo == INVALID_HANDLE_VALUE)
150 return;
151
152 do
153 {
154 ZeroMemory(&InfoData, sizeof(InfoData));
155 InfoData.cbSize = sizeof(InfoData);
156
157 if (SetupDiEnumDeviceInfo(hInfo, dwIndex, &InfoData))
158 {
159 /* set device name */
160 if (SetupDiGetDeviceInstanceId(hInfo, &InfoData, szText, sizeof(szText)/sizeof(WCHAR), NULL))
161 SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_DEVICEID, WM_SETTEXT, 0, (LPARAM)szText);
162
163 /* set the manufacturer name */
164 if (SetupDiGetDeviceRegistryPropertyW(hInfo, &InfoData, SPDRP_MFG, NULL, (PBYTE)szText, sizeof(szText), NULL))
165 SendDlgItemMessageW(hwndDlg, IDC_STATIC_ADAPTER_PROVIDER, WM_SETTEXT, 0, (LPARAM)szText);
166
167 /* FIXME
168 * we currently enumerate only the first adapter
169 */
170 hDlgCtrls[0] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_DRIVER);
171 hDlgCtrls[1] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_VERSION);
172 hDlgCtrls[2] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_DATE);
173 EnumerateDrivers(hDlgCtrls, hInfo, &InfoData);
174 break;
175 }
176
177 if (GetLastError() == ERROR_NO_MORE_ITEMS)
178 break;
179
180 dwIndex++;
181 }while(TRUE);
182
183 /* destroy the setup list */
184 SetupDiDestroyDeviceInfoList(hInfo);
185 }
186
187
188
189 BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCWSTR lpcstrDescription, LPCWSTR lpcstrModule, LPVOID lpContext)
190 {
191 PDXDIAG_CONTEXT pContext = (PDXDIAG_CONTEXT)lpContext;
192 HWND * hDlgs;
193 HWND hwndDlg;
194 WCHAR szSound[20];
195 WCHAR szText[30];
196 IDirectSound8 *pObj;
197 HRESULT hResult;
198 DWORD dwCertified;
199
200 if (!lpGuid)
201 return TRUE;
202
203 if (pContext->NumSoundAdapter)
204 hDlgs = HeapReAlloc(GetProcessHeap(), 0, pContext->hSoundWnd, (pContext->NumSoundAdapter + 1) * sizeof(HWND));
205 else
206 hDlgs = HeapAlloc(GetProcessHeap(), 0, (pContext->NumSoundAdapter + 1) * sizeof(HWND));
207
208 if (!hDlgs)
209 return FALSE;
210
211 pContext->hSoundWnd = hDlgs;
212 hwndDlg = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_SOUND_DIALOG), pContext->hMainDialog, SoundPageWndProc, (LPARAM)pContext);
213 if (!hwndDlg)
214 return FALSE;
215
216 hResult = DirectSoundCreate8(lpGuid, (LPDIRECTSOUND8*)&pObj, NULL);
217 if (hResult == DS_OK)
218 {
219 szText[0] = L'\0';
220 if (IDirectSound8_VerifyCertification(pObj, &dwCertified) == DS_OK)
221 {
222 if (dwCertified == DS_CERTIFIED)
223 LoadStringW(hInst, IDS_OPTION_YES, szText, sizeof(szText)/sizeof(WCHAR));
224 else if (dwCertified == DS_UNCERTIFIED)
225 LoadStringW(hInst, IDS_OPTION_NO, szText, sizeof(szText)/sizeof(WCHAR));
226 }
227 else
228 {
229 LoadStringW(hInst, IDS_OPTION_NO, szText, sizeof(szText)/sizeof(WCHAR));
230 }
231 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
232 SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_LOGO, WM_SETTEXT, 0, (LPARAM)szText);
233 IDirectSound8_Release(pObj);
234 }
235
236 /* set device name */
237 SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_NAME, WM_SETTEXT, 0, (LPARAM)lpcstrDescription);
238
239 /* set range for slider */
240 SendDlgItemMessageW(hwndDlg, IDC_SLIDER_DSOUND, TBM_SETRANGE, TRUE, MAKELONG(0, 3));
241
242 /* FIXME set correct position */
243 SendDlgItemMessageW(hwndDlg, IDC_SLIDER_DSOUND, TBM_SETSEL, FALSE, 0);
244
245 /* set further device details */
246 SetDeviceDetails(hwndDlg, &GUID_DEVCLASS_MEDIA, lpcstrDescription);
247
248
249
250 /* load sound resource string */
251 szSound[0] = L'\0';
252 LoadStringW(hInst, IDS_SOUND_DIALOG, szSound, sizeof(szSound)/sizeof(WCHAR));
253 szSound[(sizeof(szSound)/sizeof(WCHAR))-1] = L'\0';
254 /* output the device id */
255 wsprintfW (szText, L"%s %u", szSound, pContext->NumSoundAdapter + 1);
256 /* insert it into general tab */
257 InsertTabCtrlItem(pContext->hTabCtrl, pContext->NumDisplayAdapter + pContext->NumSoundAdapter + 1, szText);
258 /* store dialog window */
259 hDlgs[pContext->NumSoundAdapter] = hwndDlg;
260 pContext->NumSoundAdapter++;
261 return TRUE;
262 }
263
264
265 void InitializeDirectSoundPage(PDXDIAG_CONTEXT pContext)
266 {
267 HRESULT hResult;
268
269
270 /* create DSound object */
271
272 // if (hResult != DS_OK)
273 // return;
274 hResult = DirectSoundEnumerateW(DSEnumCallback, pContext);
275
276 /* release the DSound object */
277 // pObj->lpVtbl->Release(pObj);
278 (void)hResult;
279 }
280
281
282 INT_PTR CALLBACK
283 SoundPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
284 {
285 switch (message)
286 {
287 case WM_INITDIALOG:
288 {
289 SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
290 return TRUE;
291 }
292 case WM_COMMAND:
293 {
294 if (LOWORD(wParam) == IDC_BUTTON_TESTDSOUND)
295 {
296 return FALSE;
297 }
298 break;
299 }
300 }
301
302 return FALSE;
303 }