//--------------------------------------------------------------------------- // // Module: registry.c // // Description: // // //@@BEGIN_MSINTERNAL // Development Team: // Mike McLaughlin // // History: Date Author Comment // // To Do: Date Author Comment // //@@END_MSINTERNAL // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved. // //--------------------------------------------------------------------------- #include "common.h" //=========================================================================== //=========================================================================== NTSTATUS GetRegistryDefault( PSHINGLE_INSTANCE pShingleInstance, PDEVICE_NODE *ppDeviceNode ) { #ifdef REGISTRY_PREFERRED_DEVICE PKEY_VALUE_FULL_INFORMATION pkvfi = NULL; PDEVICE_NODE pDeviceNode; PGRAPH_NODE pGraphNode; PWSTR pwstrString = NULL; PWSTR pwstrPath = NULL; HANDLE hkey = NULL; NTSTATUS Status; if(pShingleInstance->pcwstrRegistryPath == NULL || pShingleInstance->pcwstrRegistryValue == NULL) { goto exit; } Status = OpenRegistryKey(pShingleInstance->pcwstrRegistryPath, &hkey); if(!NT_SUCCESS(Status)) { goto exit; } Status = QueryRegistryValue( hkey, pShingleInstance->pcwstrRegistryValue, &pkvfi); if(!NT_SUCCESS(Status)) { goto exit; } if(pkvfi->Type != REG_SZ) { Trap(); goto exit; } FOR_EACH_LIST_ITEM(gplstDeviceNode, pDeviceNode) { Status = pDeviceNode->CreateGraphNodes(); if(!NT_SUCCESS(Status)) { goto exit; } FOR_EACH_LIST_ITEM(&pDeviceNode->lstGraphNode, pGraphNode) { if((pGraphNode->ulFlags ^ pShingleInstance->ulFlags) & FLAGS_MIXER_TOPOLOGY) { continue; } Status = FindFriendlyName( pShingleInstance, ppDeviceNode, pGraphNode, (PWSTR)(((PUCHAR)pkvfi) + pkvfi->DataOffset)); if(Status != STATUS_CONTINUE) { goto exit; } } END_EACH_LIST_ITEM } END_EACH_LIST_ITEM exit: delete pkvfi; delete pwstrPath; delete pwstrString; if(hkey != NULL) { ZwClose(hkey); } #endif return(STATUS_SUCCESS); } #ifdef REGISTRY_PREFERRED_DEVICE // this registry code doesn't work under NT // and isn't needed any more ENUMFUNC FindFriendlyName( PSHINGLE_INSTANCE pShingleInstance, PDEVICE_NODE *ppDeviceNode, PGRAPH_NODE pGraphNode, PWSTR pwstr ) { NTSTATUS Status = STATUS_SUCCESS; PSTART_NODE pStartNode; ULONG c; // if "Use any available device" (registry key == empty string) if(wcslen(pwstr) == 0) { if((pGraphNode->ulFlags & pShingleInstance->ulFlags & GN_FLAGS_PREFERRED_MASK) == 0) { Status = STATUS_CONTINUE; goto exit; } *ppDeviceNode = pGraphNode->pDeviceNode; ASSERT(NT_SUCCESS(Status)); goto exit; } c = wcslen(pGraphNode->pDeviceNode->GetFriendlyName()); DPF2(100, "FindFriendlyName: %s c: %d", pGraphNode->pDeviceNode->DumpName(), c); // // The device name from the registry needs to be limited to 32 characters // (include NULL) because "pwstr" has been trunicated to this by // wdmaud.sys (the getcap structure passed back to winmm has this limit). // if(c >= MAXPNAMELEN) { c = MAXPNAMELEN - 1; // c doesn't include the NULL } if(wcsncmp(pwstr, pGraphNode->pDeviceNode->GetFriendlyName(), c) == 0) { *ppDeviceNode = pGraphNode->pDeviceNode; ASSERT(NT_SUCCESS(Status)); goto exit; } if(pShingleInstance == apShingleInstance[KSPROPERTY_SYSAUDIO_PLAYBACK_DEFAULT]) { Status = STATUS_CONTINUE; goto exit; } FOR_EACH_LIST_ITEM(&pGraphNode->lstStartNode, pStartNode) { PPIN_INFO pPinInfo; Assert(pStartNode); Assert(pStartNode->pPinNode); pPinInfo = pStartNode->pPinNode->pPinInfo; Assert(pPinInfo); if(pPinInfo->pwstrName == NULL) { continue; } if(pPinInfo->pguidName != NULL) { Trap(); continue; } if(pPinInfo->pguidCategory == NULL) { Trap(); continue; } if(!IsEqualGUID( &KSCATEGORY_WDMAUD_USE_PIN_NAME, pPinInfo->pguidCategory)) { continue; } if(wcsncmp( pwstr, pPinInfo->pwstrName, wcslen(pPinInfo->pwstrName)) == 0) { Status = GetRegistryDefault( apShingleInstance[KSPROPERTY_SYSAUDIO_PLAYBACK_DEFAULT], ppDeviceNode); goto exit; } } END_EACH_LIST_ITEM Status = STATUS_CONTINUE; exit: return(Status); } #endif #ifndef UNDER_NT NTSTATUS GetRegistryPlaybackRecordFormat( PWAVEFORMATEX pWaveFormatEx, BOOL fPlayback ) { PKEY_VALUE_FULL_INFORMATION pkvfiFormatName = NULL; PKEY_VALUE_FULL_INFORMATION pkvfiFormat = NULL; HANDLE hkeyAudio = NULL; HANDLE hkeyFormats = NULL; NTSTATUS Status; Status = OpenRegistryKey( REGSTR_PATH_MULTIMEDIA_AUDIO, &hkeyAudio); if(!NT_SUCCESS(Status)) { goto exit; } Status = QueryRegistryValue( hkeyAudio, fPlayback ? REGSTR_VAL_DEFAULT_PLAYBACK_FORMAT : REGSTR_VAL_DEFAULT_RECORD_FORMAT, &pkvfiFormatName); if(!NT_SUCCESS(Status)) { goto exit; } if(pkvfiFormatName->Type != REG_SZ) { Trap(); Status = STATUS_INVALID_DEVICE_REQUEST; goto exit; } Status = OpenRegistryKey( REGSTR_PATH_MULTIMEDIA_AUDIO_FORMATS, &hkeyFormats); if(!NT_SUCCESS(Status)) { Trap(); goto exit; } Status = QueryRegistryValue( hkeyFormats, (PCWSTR)(((PUCHAR)pkvfiFormatName) + pkvfiFormatName->DataOffset), &pkvfiFormat); if(!NT_SUCCESS(Status)) { Trap(); goto exit; } if(pkvfiFormat->Type != REG_BINARY) { Status = STATUS_INVALID_DEVICE_REQUEST; goto exit; } RtlCopyMemory( pWaveFormatEx, ((PUCHAR)pkvfiFormat) + pkvfiFormat->DataOffset, min(pkvfiFormat->DataLength, sizeof(WAVEFORMATEX))); DPF3(90, "GetRegistryPlayBackRecordFormat: SR: %d CH: %d BPS %d", pWaveFormatEx->nSamplesPerSec, pWaveFormatEx->nChannels, pWaveFormatEx->wBitsPerSample); exit: if(hkeyAudio != NULL) { ZwClose(hkeyAudio); } if(hkeyFormats != NULL) { ZwClose(hkeyFormats); } delete pkvfiFormatName; delete pkvfiFormat; return(Status); } #endif NTSTATUS OpenRegistryKey( PCWSTR pcwstr, PHANDLE pHandle, HANDLE hRootDir ) { UNICODE_STRING UnicodeDeviceString; OBJECT_ATTRIBUTES ObjectAttributes; RtlInitUnicodeString(&UnicodeDeviceString, pcwstr); InitializeObjectAttributes( &ObjectAttributes, &UnicodeDeviceString, OBJ_CASE_INSENSITIVE, hRootDir, NULL); return(ZwOpenKey( pHandle, KEY_READ | KEY_NOTIFY | KEY_WRITE, &ObjectAttributes)); } NTSTATUS QueryRegistryValue( HANDLE hkey, PCWSTR pcwstrValueName, PKEY_VALUE_FULL_INFORMATION *ppkvfi ) { UNICODE_STRING ustrValueName; NTSTATUS Status; ULONG cbValue; *ppkvfi = NULL; RtlInitUnicodeString(&ustrValueName, pcwstrValueName); Status = ZwQueryValueKey( hkey, &ustrValueName, KeyValueFullInformation, NULL, 0, &cbValue); if(Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL) { goto exit; } *ppkvfi = (PKEY_VALUE_FULL_INFORMATION)new BYTE[cbValue]; if(*ppkvfi == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; } Status = ZwQueryValueKey( hkey, &ustrValueName, KeyValueFullInformation, *ppkvfi, cbValue, &cbValue); if(!NT_SUCCESS(Status)) { delete *ppkvfi; *ppkvfi = NULL; goto exit; } exit: return(Status); }