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 12 #include <mmsystem.h> 13 #include <mmreg.h> 14 #include <dsound.h> 15 16 #if 0 17 BOOL 18 GetCatFileFromDriverPath(LPWSTR szFileName, LPWSTR szCatFileName) 19 { 20 GUID VerifyGuid = DRIVER_ACTION_VERIFY; 21 HANDLE hFile; 22 DWORD dwHash; 23 BYTE bHash[100]; 24 HCATINFO hCatInfo; 25 HCATADMIN hActAdmin; 26 BOOL bRet = FALSE; 27 CATALOG_INFO CatInfo; 28 29 /* attempt to open file */ 30 hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 31 if (hFile == INVALID_HANDLE_VALUE) 32 return FALSE; 33 34 /* calculate hash from file handle */ 35 dwHash = sizeof(bHash); 36 if (!CryptCATAdminCalcHashFromFileHandle(hFile, &dwHash, bHash, 0)) 37 { 38 CloseHandle(hFile); 39 return FALSE; 40 } 41 42 /* try open the CAT admin */ 43 if (!CryptCATAdminAcquireContext(&hActAdmin, &VerifyGuid, 0)) 44 { 45 CloseHandle(hFile); 46 return FALSE; 47 } 48 49 /* search catalog to find for catalog containing this hash */ 50 hCatInfo = CryptCATAdminEnumCatalogFromHash(hActAdmin, bHash, dwHash, 0, NULL); 51 if (hCatInfo != NULL) 52 { 53 /* theres a catalog get the filename */ 54 bRet = CryptCATCatalogInfoFromContext(hCatInfo, &CatInfo, 0); 55 if (bRet) 56 wcscpy(szCatFileName, CatInfo.wszCatalogFile); 57 CryptCATAdminReleaseCatalogContext(hActAdmin, hCatInfo, 0); 58 } 59 60 /* perform cleanup */ 61 CloseHandle(hFile); 62 CryptCATAdminReleaseContext(hActAdmin, 0); 63 return bRet; 64 } 65 66 BOOL 67 IsDriverWHQL(LPWSTR szFileName) 68 { 69 WCHAR szCatFile[MAX_PATH]; 70 HANDLE hCat; 71 BOOL bRet = FALSE; 72 73 /* get the driver's cat file */ 74 if (!GetCatFileFromDriverPath(szFileName, szCatFile)) 75 { 76 /* driver has no cat so it's definitely not WHQL signed */ 77 return FALSE; 78 } 79 80 /* open the CAT file */ 81 hCat = CryptCATOpen(szCatFile, CRYPTCAT_OPEN_EXISTING, 0, 0, 0); 82 if (hCat == INVALID_HANDLE_VALUE) 83 { 84 /* couldnt open cat */ 85 return FALSE; 86 } 87 88 /* FIXME 89 * build certificate chain with CertGetCertificateChain 90 * verify certificate chain (WinVerifyTrust) 91 * retrieve signer (WTHelperGetProvSignerFromChain) 92 */ 93 94 95 /* close CAT file */ 96 CryptCATClose(hCat); 97 return bRet; 98 } 99 #endif 100 101 static 102 void 103 SetDeviceDetails(HWND hwndDlg, LPCGUID classGUID, LPCWSTR lpcstrDescription) 104 { 105 HDEVINFO hInfo; 106 DWORD dwIndex = 0; 107 SP_DEVINFO_DATA InfoData; 108 WCHAR szText[30]; 109 HWND hDlgCtrls[3]; 110 WAVEOUTCAPSW waveOut; 111 UINT numDev; 112 MMRESULT errCode; 113 114 115 /* enumerate waveout devices */ 116 numDev = waveOutGetNumDevs(); 117 if (numDev) 118 { 119 do 120 { 121 ZeroMemory(&waveOut, sizeof(waveOut)); 122 errCode = waveOutGetDevCapsW(dwIndex++, &waveOut, sizeof(waveOut)); 123 if (!wcsncmp(lpcstrDescription, waveOut.szPname, min(MAXPNAMELEN, wcslen(waveOut.szPname)))) 124 { 125 /* set the product id */ 126 SetDlgItemInt(hwndDlg, IDC_STATIC_DSOUND_PRODUCTID, waveOut.wPid, FALSE); 127 /* set the vendor id */ 128 SetDlgItemInt(hwndDlg, IDC_STATIC_DSOUND_VENDORID, waveOut.wMid, FALSE); 129 /* check if it's a WDM audio driver */ 130 if (waveOut.wPid == MM_MSFT_WDMAUDIO_WAVEOUT) 131 SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_TYPE, WM_SETTEXT, 0, (LPARAM)L"WDM"); 132 133 /* check if device is default device */ 134 szText[0] = L'\0'; 135 if (dwIndex - 1 == 0) /* FIXME assume default playback device is device 0 */ 136 LoadStringW(hInst, IDS_OPTION_YES, szText, sizeof(szText)/sizeof(WCHAR)); 137 else 138 LoadStringW(hInst, IDS_OPTION_NO, szText, sizeof(szText)/sizeof(WCHAR)); 139 140 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; 141 /* set default device info */ 142 SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_STANDARD, WM_SETTEXT, 0, (LPARAM)szText); 143 break; 144 } 145 }while(errCode == MMSYSERR_NOERROR && dwIndex < numDev); 146 } 147 148 dwIndex = 0; 149 /* create the setup list */ 150 hInfo = SetupDiGetClassDevsW(classGUID, NULL, NULL, DIGCF_PRESENT|DIGCF_PROFILE); 151 if (hInfo == INVALID_HANDLE_VALUE) 152 return; 153 154 do 155 { 156 ZeroMemory(&InfoData, sizeof(InfoData)); 157 InfoData.cbSize = sizeof(InfoData); 158 159 if (SetupDiEnumDeviceInfo(hInfo, dwIndex, &InfoData)) 160 { 161 /* set device name */ 162 if (SetupDiGetDeviceInstanceId(hInfo, &InfoData, szText, sizeof(szText)/sizeof(WCHAR), NULL)) 163 SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_DEVICEID, WM_SETTEXT, 0, (LPARAM)szText); 164 165 /* set the manufacturer name */ 166 if (SetupDiGetDeviceRegistryPropertyW(hInfo, &InfoData, SPDRP_MFG, NULL, (PBYTE)szText, sizeof(szText), NULL)) 167 SendDlgItemMessageW(hwndDlg, IDC_STATIC_ADAPTER_PROVIDER, WM_SETTEXT, 0, (LPARAM)szText); 168 169 /* FIXME 170 * we currently enumerate only the first adapter 171 */ 172 hDlgCtrls[0] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_DRIVER); 173 hDlgCtrls[1] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_VERSION); 174 hDlgCtrls[2] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_DATE); 175 EnumerateDrivers(hDlgCtrls, hInfo, &InfoData); 176 break; 177 } 178 179 if (GetLastError() == ERROR_NO_MORE_ITEMS) 180 break; 181 182 dwIndex++; 183 }while(TRUE); 184 185 /* destroy the setup list */ 186 SetupDiDestroyDeviceInfoList(hInfo); 187 } 188 189 190 191 BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCWSTR lpcstrDescription, LPCWSTR lpcstrModule, LPVOID lpContext) 192 { 193 PDXDIAG_CONTEXT pContext = (PDXDIAG_CONTEXT)lpContext; 194 HWND * hDlgs; 195 HWND hwndDlg; 196 WCHAR szSound[20]; 197 WCHAR szText[30]; 198 IDirectSound8 *pObj; 199 HRESULT hResult; 200 DWORD dwCertified; 201 202 if (!lpGuid) 203 return TRUE; 204 205 if (pContext->NumSoundAdapter) 206 hDlgs = HeapReAlloc(GetProcessHeap(), 0, pContext->hSoundWnd, (pContext->NumSoundAdapter + 1) * sizeof(HWND)); 207 else 208 hDlgs = HeapAlloc(GetProcessHeap(), 0, (pContext->NumSoundAdapter + 1) * sizeof(HWND)); 209 210 if (!hDlgs) 211 return FALSE; 212 213 pContext->hSoundWnd = hDlgs; 214 hwndDlg = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_SOUND_DIALOG), pContext->hMainDialog, SoundPageWndProc, (LPARAM)pContext); EnableDialogTheme(hwndDlg); 215 if (!hwndDlg) 216 return FALSE; 217 218 hResult = DirectSoundCreate8(lpGuid, (LPDIRECTSOUND8*)&pObj, NULL); 219 if (hResult == DS_OK) 220 { 221 szText[0] = L'\0'; 222 if (IDirectSound8_VerifyCertification(pObj, &dwCertified) == DS_OK) 223 { 224 if (dwCertified == DS_CERTIFIED) 225 LoadStringW(hInst, IDS_OPTION_YES, szText, sizeof(szText)/sizeof(WCHAR)); 226 else if (dwCertified == DS_UNCERTIFIED) 227 LoadStringW(hInst, IDS_NOT_APPLICABLE, szText, sizeof(szText)/sizeof(WCHAR)); 228 } 229 else 230 { 231 LoadStringW(hInst, IDS_OPTION_NO, szText, sizeof(szText)/sizeof(WCHAR)); 232 } 233 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; 234 SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_LOGO, WM_SETTEXT, 0, (LPARAM)szText); 235 IDirectSound8_Release(pObj); 236 } 237 238 /* set device name */ 239 SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_NAME, WM_SETTEXT, 0, (LPARAM)lpcstrDescription); 240 241 /* set range for slider */ 242 SendDlgItemMessageW(hwndDlg, IDC_SLIDER_DSOUND, TBM_SETRANGE, TRUE, MAKELONG(0, 3)); 243 244 /* FIXME set correct position */ 245 SendDlgItemMessageW(hwndDlg, IDC_SLIDER_DSOUND, TBM_SETSEL, FALSE, 0); 246 247 /* set further device details */ 248 SetDeviceDetails(hwndDlg, &GUID_DEVCLASS_MEDIA, lpcstrDescription); 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 } 304