/****************************************************************** * PropVariantChangeType (PROPSYS.@) */ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, PROPVAR_CHANGE_FLAGS flags, VARTYPE vt) { HRESULT hr; FIXME("(%p, %p, %d, %d, %d): semi-stub!\n", ppropvarDest, propvarSrc, propvarSrc->vt, flags, vt); if(vt == propvarSrc->vt) return PropVariantCopy(ppropvarDest, propvarSrc); switch (vt) { case VT_I2: { SHORT res; hr = PropVariantToInt16(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I2; ppropvarDest->u.iVal = res; } return hr; } case VT_UI2: { USHORT res; hr = PropVariantToUInt16(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI2; ppropvarDest->u.uiVal = res; } return hr; } case VT_I4: { LONG res; hr = PropVariantToInt32(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I4; ppropvarDest->u.lVal = res; } return hr; } case VT_UI4: { ULONG res; hr = PropVariantToUInt32(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI4; ppropvarDest->u.ulVal = res; } return hr; } case VT_I8: { LONGLONG res; hr = PropVariantToInt64(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I8; ppropvarDest->u.hVal.QuadPart = res; } return hr; } case VT_UI8: { ULONGLONG res; hr = PropVariantToUInt64(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI8; ppropvarDest->u.uhVal.QuadPart = res; } return hr; } case VT_LPWSTR: { WCHAR *res; hr = PropVariantToStringAlloc(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_LPWSTR; ppropvarDest->u.pwszVal = res; } return hr; } } switch (propvarSrc->vt) { case VT_FILETIME: return PROPVAR_ConvertFILETIME(ppropvarDest, propvarSrc, vt); default: FIXME("Unhandled source type: %d\n", propvarSrc->vt); } return E_FAIL; }
/****************************************************************** * PropVariantChangeType (PROPSYS.@) */ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, PROPVAR_CHANGE_FLAGS flags, VARTYPE vt) { HRESULT hr; FIXME("(%p, %p, %d, %d, %d): semi-stub!\n", ppropvarDest, propvarSrc, propvarSrc->vt, flags, vt); if (vt == propvarSrc->vt) return PropVariantCopy(ppropvarDest, propvarSrc); if (propvarSrc->vt == VT_FILETIME) return PROPVAR_ConvertFILETIME(&propvarSrc->u.filetime, ppropvarDest, vt); switch (vt) { case VT_I1: { LONGLONG res; hr = PROPVAR_ConvertNumber(propvarSrc, 8, TRUE, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I1; ppropvarDest->u.cVal = (char)res; } return hr; } case VT_UI1: { LONGLONG res; hr = PROPVAR_ConvertNumber(propvarSrc, 8, FALSE, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI1; ppropvarDest->u.bVal = (UCHAR)res; } return hr; } case VT_I2: { SHORT res; hr = PropVariantToInt16(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I2; ppropvarDest->u.iVal = res; } return hr; } case VT_UI2: { USHORT res; hr = PropVariantToUInt16(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI2; ppropvarDest->u.uiVal = res; } return hr; } case VT_I4: { LONG res; hr = PropVariantToInt32(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I4; ppropvarDest->u.lVal = res; } return hr; } case VT_UI4: { ULONG res; hr = PropVariantToUInt32(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI4; ppropvarDest->u.ulVal = res; } return hr; } case VT_I8: { LONGLONG res; hr = PropVariantToInt64(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I8; ppropvarDest->u.hVal.QuadPart = res; } return hr; } case VT_UI8: { ULONGLONG res; hr = PropVariantToUInt64(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI8; ppropvarDest->u.uhVal.QuadPart = res; } return hr; } case VT_LPWSTR: case VT_BSTR: { WCHAR *res; hr = PropVariantToStringAlloc(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_LPWSTR; ppropvarDest->u.pwszVal = res; } return hr; } case VT_LPSTR: { WCHAR *resW; hr = PropVariantToStringAlloc(propvarSrc, &resW); if (SUCCEEDED(hr)) { char *res; DWORD len; len = WideCharToMultiByte(CP_ACP, 0, resW, -1, NULL, 0, NULL, NULL); res = CoTaskMemAlloc(len); if (res) { WideCharToMultiByte(CP_ACP, 0, resW, -1, res, len, NULL, NULL); ppropvarDest->vt = VT_LPSTR; ppropvarDest->u.pszVal = res; } else hr = E_OUTOFMEMORY; CoTaskMemFree(resW); } return hr; } default: FIXME("Unhandled dest type: %d\n", vt); return E_FAIL; } }
bool EnumBuiltinDevices_w64(const uint32_t deviceType, STUDIO_LINK_DEVICE_LIST* devices) { PRECONDITION_RETURN(deviceType != INVALID_DEVICE_TYPE, false); PRECONDITION_RETURN(devices != 0, false); bool result = false; HRESULT hr = CoInitialize(0); if(SUCCEEDED(hr)) { IMMDeviceEnumerator* pDeviceEnumerator = 0; hr = CoCreateInstance(CLSID_MMDeviceEnumerator, 0, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator); if(SUCCEEDED(hr) && (pDeviceEnumerator != 0)) { EDataFlow dataFlow = eAll; if(deviceType == HEADPHONE) { dataFlow = eRender; } else if(deviceType == MICROPHONE) { dataFlow = eCapture; } IMMDeviceCollection* pDeviceCollection = 0; hr = pDeviceEnumerator->EnumAudioEndpoints(dataFlow, DEVICE_STATE_ACTIVE, &pDeviceCollection); if(SUCCEEDED(hr) && (pDeviceCollection != 0)) { UINT deviceCount = 0; hr = pDeviceCollection->GetCount(&deviceCount); if(SUCCEEDED(hr)) { size_t foundDevices = 0; for(UINT i = 0; (i < deviceCount) && (foundDevices < deviceCount); i++) { IMMDevice* pDevice = 0; hr = pDeviceCollection->Item(i, &pDevice); if(SUCCEEDED(hr) && (pDevice != 0)) { IPropertyStore* pProperties = 0; hr = pDevice->OpenPropertyStore(STGM_READ, &pProperties); if(SUCCEEDED(hr)) { PROPVARIANT deviceFormatProperty; PropVariantInit(&deviceFormatProperty); hr = pProperties->GetValue(PKEY_AudioEngine_DeviceFormat, &deviceFormatProperty); if(SUCCEEDED(hr) && (VT_BLOB == deviceFormatProperty.vt)) { WAVEFORMATEX* deviceFormat = (WAVEFORMATEX*)deviceFormatProperty.blob.pBlobData; devices->devices[foundDevices].channelCount = deviceFormat->nChannels; devices->devices[foundDevices].sampleRate = deviceFormat->nSamplesPerSec; if((WAVE_FORMAT_EXTENSIBLE == deviceFormat->wFormatTag) && (deviceFormat->cbSize >= 22)) { //WAVEFORMATEXTENSIBLE* extensibleDeviceFormat = (WAVEFORMATEXTENSIBLE*)deviceFormat; } PropVariantClear(&deviceFormatProperty); PROPVARIANT deviceNameProperty; PropVariantInit(&deviceNameProperty); hr = pProperties->GetValue(PKEY_Device_FriendlyName, &deviceNameProperty); if(SUCCEEDED(hr)) { PWSTR deviceName = 0; hr = PropVariantToStringAlloc(deviceNameProperty, &deviceName); if(SUCCEEDED(hr)) { memset(devices->devices[foundDevices].name, 0, STUDIO_LINK_DEVICE_NAME_LENGTH); size_t numOfCharsConverted = 0; const size_t deviceNameLength = wcslen(deviceName); wcstombs_s(&numOfCharsConverted, devices->devices[foundDevices].name, STUDIO_LINK_DEVICE_NAME_LENGTH, deviceName, deviceNameLength); foundDevices++; CoTaskMemFree(deviceName); deviceName = 0; } PropVariantClear(&deviceNameProperty); } } SafeRelease(pProperties); } SafeRelease(pDevice); } } devices->deviceCount = foundDevices; } SafeRelease(pDeviceCollection); } SafeRelease(pDeviceEnumerator); } CoUninitialize(); } if(devices->deviceCount > 0) { result = true; } return result; }
void MediaSource::LoadMetadataFromSource() { IMFMetadataProvider* mfMetadataProvider = nullptr; IMFMetadata* mfMetadata = nullptr; PROPVARIANT metadataKeys, metadataValue; PWSTR *metadataPropertyKeys = nullptr; HRESULT hr; _metadataPropertyCount = 0; PropVariantInit(&metadataKeys); PropVariantInit(&metadataValue); do { if (!SUCCEEDED(hr = MFGetService(_mfMediaSource, MF_METADATA_PROVIDER_SERVICE, IID_PPV_ARGS(&mfMetadataProvider)))) { // Can't get the metadata provider service for this media source, but that's ok... we'll just skip reading metadata hr = S_OK; break; } if (!SUCCEEDED(hr = mfMetadataProvider->GetMFMetadata(_mfPresentationDescriptor, 0, 0, &mfMetadata))) break; if (!SUCCEEDED(hr = mfMetadata->GetAllPropertyNames(&metadataKeys))) break; if (!SUCCEEDED(hr = PropVariantToStringVectorAlloc(metadataKeys, &metadataPropertyKeys, &_metadataPropertyCount))) break; _metadata = (MetadataKeyValuePair *)malloc(_metadataPropertyCount * sizeof(MetadataKeyValuePair)); for (ULONG i = 0; i < _metadataPropertyCount; i++) { PWSTR metadataKey = *(metadataPropertyKeys + i); if (!SUCCEEDED(hr = mfMetadata->GetProperty(metadataKey, &metadataValue))) break; (_metadata + i)->Key = metadataKey; if (!SUCCEEDED(hr = PropVariantToStringAlloc(metadataValue, &((_metadata + i)->Value)))) break; PropVariantClear(&metadataValue); } if (FAILED(hr)) break; } while (0); if (metadataPropertyKeys) CoTaskMemFree(metadataPropertyKeys); if (mfMetadata) mfMetadata->Release(); if (mfMetadataProvider) mfMetadataProvider->Release(); if (FAILED(hr)) { throw std::exception("Error occurred reading metadata from media source"); } }