/* *************************************************************** * sprop.c * * Copyright (C) Microsoft, 1990, All Rights Reserved. * * Displays the Simple media properties * * History: * * July 1994 -by- VijR (Created) * *************************************************************** */ #include "mmcpl.h" #include #ifdef DEBUG #undef DEBUG #include #define DEBUG #else #include #endif #include #include #include #include #include #include "utils.h" #include "medhelp.h" #include "mmcpl.h" #include //for digital cd audio #include "devguid.h" #include "setupapi.h" #include "cfgmgr32.h" #include "winioctl.h" #include "tchar.h" const TCHAR gszCreateCDFile[] = TEXT("\\\\.\\%c:"); #define MYREGSTR_PATH_MEDIA TEXT("SYSTEM\\CurrentControlSet\\Control\\MediaResources") const TCHAR gszRegstrCDAPath[] = MYREGSTR_PATH_MEDIA TEXT("\\mci\\cdaudio"); const TCHAR gszUnitEnum[] = TEXT("%s\\unit %d"); const TCHAR gszSettingsKey[] = TEXT("Volume Settings"); const TCHAR gszDefaultCDA[] = TEXT("Default Drive"); const TCHAR gszRegstrCDROMPath[] = TEXT("System\\CurrentControlSet\\Services\\Class\\CDROM\\"); const TCHAR gszDigitalPlay[] = TEXT("DigitalAudioPlay"); const TCHAR gszRegstrDrivePath[] = TEXT("Enum\\SCSI"); #define CDA_VT_UNSET 0 #define CDA_VT_AUX 1 #define CDA_VT_MIX 2 #define CDROM_DIGITAL_PLAY_ENABLED 0x01 #define CDROM_DIGITAL_PLAY_CAPABLE 0x02 #define CDROM_DIGITAL_DEVICE_KNOWN 0x04 typedef struct { // This struct is used in other places DO NOT CHANGE DWORD unit; DWORD dwVol; } CDAREG, *PCDAREG; typedef struct { // This is now the local version with addition data, this can change, but has to keep the CDAREG cdar; BOOLEAN fDigFlags; BOOLEAN DigitalEnabled; BOOLEAN DigitalKnownDevice; BOOLEAN oldDigEnabled; DWORD dwOldVol; TCHAR chDrive; HDEVINFO hDevInfo; PSP_DEVINFO_DATA pDevInfoData; } CDSTATE, *PCDSTATE; BOOL g_fWDMEnabled = FALSE; HMODULE g_hModStorProp = NULL; typedef LONG (WINAPI *CDROMISDIGITALPLAYBACKENABLEDPROC)(HDEVINFO,PSP_DEVINFO_DATA,BOOLEAN*); typedef BOOL (WINAPI *CDROMKNOWNGOODDIGITALPLAYBACKPROC)(HDEVINFO,PSP_DEVINFO_DATA); typedef LONG (WINAPI *CDROMENABLEDIGITALPLAYBACKPROC)(HDEVINFO,PSP_DEVINFO_DATA,BOOLEAN); typedef LONG (WINAPI *CDROMDISABLEDIGITALPLAYBACKPROC)(HDEVINFO,PSP_DEVINFO_DATA); CDROMISDIGITALPLAYBACKENABLEDPROC _gCdromIsDigitalPlaybackEnabled = NULL; CDROMKNOWNGOODDIGITALPLAYBACKPROC _gCdromKnownGoodDigitalPlayback = NULL; CDROMENABLEDIGITALPLAYBACKPROC _gCdromEnableDigitalPlayback = NULL; CDROMDISABLEDIGITALPLAYBACKPROC _gCdromDisableDigitalPlayback = NULL; void GetPrefInfo(PAUDIODLGINFO pai, HWND hDlg ); HANDLE GetHandleForDevice(LPCTSTR DeviceName) { int i = 0; TCHAR fakeDeviceName[MAX_PATH]; HANDLE h = INVALID_HANDLE_VALUE; BOOL success = FALSE; TCHAR buf[MAX_PATH]; while (!success && i < 10) { wsprintf(buf, TEXT("DISK_FAKE_DEVICE_%d_"), i++); success = DefineDosDevice(DDD_RAW_TARGET_PATH, buf, DeviceName); if (success) { _tcscpy(fakeDeviceName, TEXT("\\\\.\\")); _tcscat(fakeDeviceName, buf); h = CreateFile(fakeDeviceName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); DefineDosDevice(DDD_REMOVE_DEFINITION, buf, NULL); } } //end while return h; } HANDLE GetHandleForDeviceInst(DEVINST DevInst) { TCHAR DeviceName[MAX_PATH]; CONFIGRET cr; DWORD len = MAX_PATH; cr = CM_Get_DevNode_Registry_Property(DevInst, CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME, NULL, DeviceName, &len, 0); if (cr != CR_SUCCESS) { return 0; } return GetHandleForDevice(DeviceName); } BOOL EnableCdromFunctions(HMODULE* pMod) { BOOL fRet = FALSE; if (!*pMod) { *pMod = LoadLibrary(TEXT("STORPROP.DLL")); } if (*pMod) { _gCdromIsDigitalPlaybackEnabled = (CDROMISDIGITALPLAYBACKENABLEDPROC)GetProcAddress(*pMod,"CdromIsDigitalPlaybackEnabled"); _gCdromKnownGoodDigitalPlayback = (CDROMKNOWNGOODDIGITALPLAYBACKPROC)GetProcAddress(*pMod,"CdromKnownGoodDigitalPlayback"); _gCdromEnableDigitalPlayback = (CDROMENABLEDIGITALPLAYBACKPROC)GetProcAddress(*pMod,"CdromEnableDigitalPlayback"); _gCdromDisableDigitalPlayback = (CDROMDISABLEDIGITALPLAYBACKPROC)GetProcAddress(*pMod,"CdromDisableDigitalPlayback"); if ( (_gCdromIsDigitalPlaybackEnabled) && (_gCdromKnownGoodDigitalPlayback) && (_gCdromEnableDigitalPlayback) && (_gCdromDisableDigitalPlayback) ) { fRet = TRUE; } } return fRet; } BYTE CDAudio_GetSetDigitalFlags(PCDSTATE pcds, BYTE fSetFlags, BOOL fSet) { BYTE bFlags = 0; BOOLEAN bEnabled = FALSE; if (EnableCdromFunctions(&g_hModStorProp)) { bFlags = 0; if (fSet) { BOOLEAN bEnable = fSetFlags & CDROM_DIGITAL_PLAY_ENABLED; BOOLEAN bAlready = FALSE; _gCdromIsDigitalPlaybackEnabled(pcds->hDevInfo,pcds->pDevInfoData,&bAlready); if (bEnable != bAlready) { if (bEnable) { _gCdromEnableDigitalPlayback(pcds->hDevInfo,pcds->pDevInfoData,FALSE); } else { _gCdromDisableDigitalPlayback(pcds->hDevInfo,pcds->pDevInfoData); } } } //always do a get after a set _gCdromIsDigitalPlaybackEnabled(pcds->hDevInfo,pcds->pDevInfoData,&bEnabled); if (bEnabled) { bFlags |= CDROM_DIGITAL_PLAY_ENABLED; } if (_gCdromKnownGoodDigitalPlayback(pcds->hDevInfo,pcds->pDevInfoData)) { bFlags |= CDROM_DIGITAL_DEVICE_KNOWN; } } return bFlags; } BYTE CDAudio_SetDigitalFlags(PCDSTATE pcds, BYTE fDigFlags) { return CDAudio_GetSetDigitalFlags(pcds,fDigFlags,TRUE); } BYTE CDAudio_GetDigitalFlags(PCDSTATE pcds) { return CDAudio_GetSetDigitalFlags(pcds,0,FALSE); } /* * */ void CDAudio_GetRegData(PCDSTATE pcds,ULONG uDrive) { TCHAR szRegstrCDAudio[_MAX_PATH]; HKEY hkTmp; if (!pcds) return; wsprintf(szRegstrCDAudio, gszUnitEnum, gszRegstrCDAPath, uDrive); pcds->cdar.dwVol = 0xFF; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE , szRegstrCDAudio , 0 , KEY_READ , &hkTmp ) == ERROR_SUCCESS) { DWORD cbCDA = sizeof(CDAREG); RegQueryValueEx(hkTmp , gszSettingsKey , NULL , NULL , (LPBYTE)&pcds->cdar , &cbCDA); RegCloseKey(hkTmp); } pcds->cdar.unit = uDrive; pcds->fDigFlags = CDAudio_GetDigitalFlags(pcds); pcds->DigitalEnabled = pcds->fDigFlags & CDROM_DIGITAL_PLAY_ENABLED; pcds->DigitalKnownDevice = pcds->fDigFlags & CDROM_DIGITAL_DEVICE_KNOWN; pcds->oldDigEnabled = pcds->DigitalEnabled; pcds->dwOldVol = pcds->cdar.dwVol; } /* * */ void CDAudio_SetRegData( PCDSTATE pcds, HWND hwnd) { TCHAR szRegstrCDAudio[_MAX_PATH]; HKEY hkTmp; BYTE bFlags = 0; wsprintf(szRegstrCDAudio, gszUnitEnum, gszRegstrCDAPath, pcds->cdar.unit); if (RegCreateKeyEx(HKEY_LOCAL_MACHINE , szRegstrCDAudio , 0 , NULL , 0 , KEY_WRITE , NULL , &hkTmp , NULL ) == ERROR_SUCCESS) { RegSetValueEx(hkTmp , gszSettingsKey , 0L , REG_BINARY , (LPBYTE)&pcds->cdar , sizeof(CDAREG)); RegCloseKey(hkTmp); } if (pcds->DigitalEnabled) { pcds->fDigFlags |= CDROM_DIGITAL_PLAY_ENABLED; } else { pcds->fDigFlags &= ~CDROM_DIGITAL_PLAY_ENABLED; } bFlags = CDAudio_SetDigitalFlags(pcds,pcds->fDigFlags); //check for success if ((bFlags & CDROM_DIGITAL_PLAY_ENABLED) != (pcds->DigitalEnabled)) { pcds->DigitalEnabled = bFlags & CDROM_DIGITAL_PLAY_ENABLED; Button_SetCheck(GetDlgItem(hwnd, IDC_CDEN_DIGAUDIO), pcds->DigitalEnabled); } } void ChangeCDVolume(PCDSTATE pcds) { MCI_OPEN_PARMS mciOpen; TCHAR szElementName[4]; TCHAR szAliasName[32]; DWORD dwFlags; DWORD dwAliasCount = GetCurrentTime(); DWORD dwRet; CDAREG cdarCache; HKEY hkTmp; TCHAR szRegstrCDAudio[_MAX_PATH]; ASSERT(pcds); if (pcds != NULL) { wsprintf(szRegstrCDAudio, gszUnitEnum, gszRegstrCDAPath, pcds->cdar.unit); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE , szRegstrCDAudio , 0 , KEY_READ , &hkTmp ) == ERROR_SUCCESS) { DWORD cbCDA = sizeof(CDAREG); RegQueryValueEx(hkTmp , gszSettingsKey , NULL , NULL , (LPBYTE)&cdarCache , &cbCDA); RegCloseKey(hkTmp); } else { cdarCache = pcds->cdar; } if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szRegstrCDAudio, 0, NULL, 0, KEY_WRITE, NULL, &hkTmp, NULL ) == ERROR_SUCCESS) { CDAREG cdar; cdar = pcds->cdar; RegSetValueEx(hkTmp , gszSettingsKey , 0L , REG_BINARY , (LPBYTE)&cdar , sizeof(CDAREG)); RegCloseKey(hkTmp); } ZeroMemory( &mciOpen, sizeof(mciOpen) ); mciOpen.lpstrDeviceType = (LPTSTR)MCI_DEVTYPE_CD_AUDIO; wsprintf( szElementName, TEXT("%c:"), pcds->chDrive ); wsprintf( szAliasName, TEXT("SJE%lu:"), dwAliasCount ); mciOpen.lpstrElementName = szElementName; mciOpen.lpstrAlias = szAliasName; dwFlags = MCI_OPEN_ELEMENT | MCI_OPEN_ALIAS | MCI_OPEN_SHAREABLE | MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_WAIT; dwRet = mciSendCommand(0, MCI_OPEN, dwFlags, (DWORD_PTR)(LPVOID)&mciOpen); if ( dwRet == MMSYSERR_NOERROR ) { mciSendCommand(mciOpen.wDeviceID, MCI_CLOSE, 0L, 0L ); } if (RegOpenKeyEx(HKEY_LOCAL_MACHINE , szRegstrCDAudio , 0 , KEY_WRITE , &hkTmp ) == ERROR_SUCCESS) { RegSetValueEx(hkTmp , gszSettingsKey , 0L , REG_BINARY , (LPBYTE)&cdarCache , sizeof(CDAREG)); RegCloseKey(hkTmp); } } } /* * */ void CDAudio_SaveState( HWND hwnd) { PCDSTATE pcds; pcds = (PCDSTATE)GetWindowLongPtr(hwnd,DWLP_USER); if (pcds) { CDAudio_SetRegData(pcds,hwnd); pcds->oldDigEnabled = pcds->DigitalEnabled; pcds->dwOldVol = pcds->cdar.dwVol; ChangeCDVolume(pcds); } } void CDAudio_DigitalPlaybackEnable(HWND hDlg) { PCDSTATE pcds; pcds = (PCDSTATE)GetWindowLongPtr(hDlg,DWLP_USER); if (pcds) { pcds->DigitalEnabled = (BOOLEAN)Button_GetCheck(GetDlgItem(hDlg, IDC_CDEN_DIGAUDIO)); } } ULONG MatchDriveToDevInst(DWORD DevInst) { HANDLE hMatch = INVALID_HANDLE_VALUE; STORAGE_DEVICE_NUMBER sDevice, sMatch; DWORD bytesReturned; ULONG uRet = 0; if (INVALID_HANDLE_VALUE != (hMatch = GetHandleForDeviceInst(DevInst))) { if (DeviceIoControl(hMatch, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sMatch, sizeof(STORAGE_DEVICE_NUMBER), &bytesReturned, NULL)) { uRet = sMatch.DeviceNumber; } CloseHandle(hMatch); } return uRet; } /* * */ DWORD CDAudio_InitDrives(HWND hwnd, PCDSTATE pcds) { DWORD cch; DWORD cCDs = 0; ULONG uDrive = 0; uDrive = MatchDriveToDevInst(pcds->pDevInfoData->DevInst); CDAudio_GetRegData(pcds,uDrive); if (cch = GetLogicalDriveStrings(0, NULL)) { LPTSTR lpDrives,lp; lp = lpDrives = GlobalAllocPtr(GHND, cch * sizeof(TCHAR)); cch = GetLogicalDriveStrings(cch, lpDrives); if (lpDrives && cch) { // upon the last drive enumerated, there will be a double // null termination while (*lpDrives) { if (GetDriveType(lpDrives) == DRIVE_CDROM) { int i; LPTSTR lp; lp = CharUpper(lpDrives); while (*lp != TEXT('\\')) lp = CharNext(lp); while (*lp) { *lp = TEXT(' '); lp = CharNext(lp); } if (cCDs == uDrive) { pcds->chDrive = lpDrives[0]; } cCDs++; } for ( ; *lpDrives ; lpDrives++ ); lpDrives++; } } if (lp) GlobalFreePtr(lp); } return cCDs; } // // Determines what device is currently being used by the mapper to play audio // MMRESULT GetWaveID(UINT *puWaveID) { PAUDIODLGINFO pInfo = (PAUDIODLGINFO)LocalAlloc(LPTR, sizeof(AUDIODLGINFO));; if (!pInfo) return MMSYSERR_NOMEM; GetPrefInfo(pInfo, NULL); if(-1 == pInfo->uPrefOut) { LocalFree((HLOCAL)pInfo); return MMSYSERR_BADDEVICEID; } *puWaveID = pInfo->uPrefOut; LocalFree((HLOCAL)pInfo); return MMSYSERR_NOERROR; } // // Checks to see if the current output audio device is a WDM Device or not // BOOL WDMAudioEnabled(void) { BOOL fResult = FALSE; UINT uWaveID; if (GetWaveID(&uWaveID) == MMSYSERR_NOERROR) { WAVEOUTCAPS woc; if (waveOutGetDevCaps(uWaveID, &woc, sizeof(WAVEOUTCAPS)) == MMSYSERR_NOERROR) { if ((woc.wMid == MM_MICROSOFT) && (woc.wPid == MM_MSFT_WDMAUDIO_WAVEOUT)) { fResult = TRUE; } } } return(fResult); } BOOL CDAudio_OnInitDialog( HWND hwnd, HWND hwndFocus, LPARAM lParam) { HWND hwndTB1 = GetDlgItem(hwnd, IDC_CD_TB_VOLUME); HWND hwndCK3 = GetDlgItem(hwnd, IDC_CDEN_DIGAUDIO); HWND hwndTX1 = GetDlgItem(hwnd, IDC_TEXT_24); UINT uDrive; int i; PCDSTATE pcds = NULL; PALLDEVINFO pDevInfo = NULL; pcds = (PCDSTATE)GlobalAllocPtr(GHND, sizeof(CDSTATE)); if (!pcds) return FALSE; SetWindowLongPtr(hwnd,DWLP_USER,(LONG_PTR)pcds); pDevInfo = (ALLDEVINFO *) ((LPPROPSHEETPAGE) lParam)->lParam; if (pDevInfo) { pcds->hDevInfo = pDevInfo->hDevInfo; pcds->pDevInfoData = pDevInfo->pDevInfoData; GlobalFreePtr(pDevInfo); ((LPPROPSHEETPAGE) lParam)->lParam = (LPARAM) NULL; } SendMessage(hwndTB1, TBM_SETTICFREQ, 10, 0); SendMessage(hwndTB1, TBM_SETRANGE, FALSE, MAKELONG(0,100)); i = CDAudio_InitDrives(hwnd,pcds); if (i) { if (pcds) { SendMessage(hwndTB1, TBM_SETPOS, TRUE, (pcds->cdar.dwVol * 100L)/255L ); Button_SetCheck(hwndCK3, pcds->DigitalEnabled); } g_fWDMEnabled = WDMAudioEnabled(); // if (!g_fWDMEnabled) // Per bug 20964, never disable "Enable Digital CD" checkbox // { // EnableWindow(hwndCK3, FALSE); // EnableWindow(hwndTX1, FALSE); // } } // else // { // EnableWindow(hwndCK3, FALSE); // EnableWindow(hwndTB1, FALSE); // EnableWindow(hwndTX1, FALSE); // } return FALSE; } void CDToggleApply(HWND hDlg) { PCDSTATE pcds; BOOL fChanged = FALSE; pcds = (PCDSTATE)GetWindowLongPtr(hDlg,DWLP_USER); if (pcds) { if (pcds->DigitalEnabled != pcds->oldDigEnabled) { fChanged = TRUE; } if (pcds->dwOldVol != pcds->cdar.dwVol) { fChanged = TRUE; } } if (fChanged) { PropSheet_Changed(GetParent(hDlg),hDlg); } else { PropSheet_UnChanged(GetParent(hDlg),hDlg); } } void CDAudio_OnDestroy( HWND hwnd) { PCDSTATE lp = (PCDSTATE)GetWindowLongPtr(hwnd,DWLP_USER); if (lp) GlobalFreePtr(lp); if (g_hModStorProp) { FreeLibrary(g_hModStorProp); g_hModStorProp = NULL; } } void CDAudio_OnHScroll( HWND hwnd, HWND hwndCtl, UINT code, int pos) { if (code == TB_ENDTRACK || code == SB_THUMBTRACK) { HWND hwndTB1 = GetDlgItem(hwnd, IDC_CD_TB_VOLUME); int i; PCDSTATE pcds; DWORD dwVol; pcds = (PCDSTATE)GetWindowLongPtr(hwnd,DWLP_USER); if (CB_ERR != (UINT_PTR) pcds && pcds) { dwVol = (((DWORD)SendMessage(hwndTB1, TBM_GETPOS, 0, 0)) * 255L) / 100L; if (dwVol != pcds->cdar.dwVol) { pcds->cdar.dwVol = dwVol; ChangeCDVolume(pcds); CDToggleApply(hwnd); } } } } void CDAudio_OnCancel( HWND hwnd) { PCDSTATE pcds; pcds = (PCDSTATE)GetWindowLongPtr(hwnd,DWLP_USER); pcds->cdar.dwVol = pcds->dwOldVol; ChangeCDVolume(pcds); } BOOL PASCAL CDAudio_OnCommand( HWND hDlg, int id, HWND hwndCtl, UINT codeNotify) { BOOL fResult = FALSE; switch (id) { case ID_APPLY: { CDAudio_SaveState(hDlg); fResult = TRUE; } break; case IDCANCEL: { CDAudio_OnCancel(hDlg); fResult = TRUE; } break; case IDC_CDEN_DIGAUDIO: { CDAudio_DigitalPlaybackEnable(hDlg); CDToggleApply(hDlg); } break; } return fResult; } const static DWORD aCDHelpIds[] = { // Context Help IDs IDI_CDAUDIO, IDH_COMM_GROUPBOX, IDC_ICON_5, IDH_COMM_GROUPBOX, IDC_TEXT_25, IDH_COMM_GROUPBOX, IDC_GROUPBOX, IDH_COMM_GROUPBOX, IDC_GROUPBOX_2, IDH_COMM_GROUPBOX, IDC_TEXT_29, IDH_CD_VOL_HEADPHONE, IDC_CD_TB_VOLUME, IDH_CD_VOL_HEADPHONE, IDC_TEXT_30, IDH_CD_VOL_HEADPHONE, IDC_TEXT_24, IDH_CDROM_PROPERTIES_DIGITAL, IDC_CDEN_DIGAUDIO, IDH_CDROM_PROPERTIES_DIGITAL, 0, 0 }; BOOL CALLBACK CDDlg( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { NMHDR FAR *lpnm; switch (uMsg) { case WM_NOTIFY: lpnm = (NMHDR FAR *)lParam; switch(lpnm->code) { case PSN_KILLACTIVE: FORWARD_WM_COMMAND(hDlg, IDOK, 0, 0, SendMessage); break; case PSN_APPLY: FORWARD_WM_COMMAND(hDlg, ID_APPLY, 0, 0, SendMessage); break; case PSN_SETACTIVE: FORWARD_WM_COMMAND(hDlg, ID_INIT, 0, 0, SendMessage); break; case PSN_RESET: FORWARD_WM_COMMAND(hDlg, IDCANCEL, 0, 0, SendMessage); break; } break; case WM_INITDIALOG: HANDLE_WM_INITDIALOG(hDlg, wParam, lParam, CDAudio_OnInitDialog); break; case WM_DESTROY: HANDLE_WM_DESTROY(hDlg, wParam, lParam, CDAudio_OnDestroy); break; case WM_DROPFILES: break; case WM_CONTEXTMENU: WinHelp((HWND)wParam, gszWindowsHlp, HELP_CONTEXTMENU, (UINT_PTR)(LPTSTR)aCDHelpIds); break; case WM_HELP: WinHelp(((LPHELPINFO)lParam)->hItemHandle, gszWindowsHlp, HELP_WM_HELP, (UINT_PTR)(LPTSTR)aCDHelpIds); break; case WM_COMMAND: HANDLE_WM_COMMAND(hDlg, wParam, lParam, CDAudio_OnCommand); break; case WM_HSCROLL: HANDLE_WM_HSCROLL(hDlg, wParam, lParam, CDAudio_OnHScroll); break; #if 0 default: if (uMsg == wHelpMessage) { WinHelp(hDlg, gszWindowsHlp, HELP_CONTEXT, ID_SND_HELP); return TRUE; } break; #endif } return FALSE; }