HRESULT BthLEDevice::SetPropertyValues( ACCESS_SCOPE Scope, _In_ LPCWSTR wszObjectID, _In_ IPortableDeviceValues* pValues, _Inout_ IPortableDeviceValues* pResults, _Inout_ IPortableDeviceValues* pEventParams, _Out_ bool* pbObjectChanged) { HRESULT hr = S_OK; AbstractDeviceContent* pContent = NULL; if ((wszObjectID == NULL) || (pValues == NULL) || (pResults == NULL) || (pEventParams == NULL) || (pbObjectChanged == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } *pbObjectChanged = FALSE; hr = GetContent(Scope, wszObjectID, &pContent); CHECK_HR(hr, "Failed to get content '%ws'", wszObjectID); if (hr == S_OK) { hr = pContent->WriteValues(pValues, pResults, pbObjectChanged); CHECK_HR(hr, "Failed to write value for '%ws'", wszObjectID); if (SUCCEEDED(hr) && (*pbObjectChanged)) // hr can be S_OK or S_FALSE (if one or more property writes failed) { HRESULT hrEvent = pEventParams->SetGuidValue(WPD_EVENT_PARAMETER_EVENT_ID, WPD_EVENT_OBJECT_UPDATED); CHECK_HR(hrEvent, "Failed to add WPD_EVENT_PARAMETER_EVENT_ID"); if (hrEvent == S_OK) { hrEvent = pEventParams->SetStringValue(WPD_OBJECT_PERSISTENT_UNIQUE_ID, pContent->PersistentUniqueID); CHECK_HR(hrEvent, "Failed to add WPD_OBJECT_PERSISTENT_UNIQUE_ID"); } if (hrEvent == S_OK) { hrEvent = pEventParams->SetStringValue(WPD_EVENT_PARAMETER_OBJECT_PARENT_PERSISTENT_UNIQUE_ID, pContent->ParentPersistentUniqueID); CHECK_HR(hrEvent, "Failed to add WPD_EVENT_PARAMETER_OBJECT_PARENT_PERSISTENT_UNIQUE_ID"); } if (hrEvent == S_OK) { // Adding this event parameter will allow WPD to scope this event to the container functional object hrEvent = pEventParams->SetStringValue(WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID, pContent->ContainerFunctionalObjectID); CHECK_HR(hrEvent, "Failed to add WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID"); } } } return hr; }
HRESULT AbstractDeviceContent::RemoveObjectsMarkedForDeletion( ACCESS_SCOPE Scope) { HRESULT hr = S_OK; DWORD dwIndex = 0; AbstractDeviceContent* pChild = NULL; CComCritSecLock<CComAutoCriticalSection> Lock(m_ChildrenCS); while (FindNext(Scope, dwIndex, &pChild)) { if (pChild != NULL) { hr = pChild->RemoveObjectsMarkedForDeletion(Scope); CHECK_HR(hr, "Failed to remove children marked for deletion for object '%ws'", pChild->ObjectID); if ((hr == S_OK) && (pChild->MarkedForDeletion == true)) { m_Children.RemoveAt(dwIndex); delete pChild; pChild = NULL; } } dwIndex++; } m_Children.FreeExtra(); return hr; }
HRESULT BthLEDevice::GetPropertyAtributes( ACCESS_SCOPE Scope, _In_ LPCWSTR wszObjectID, REFPROPERTYKEY Key, _Inout_ IPortableDeviceValues* pAttributes) { HRESULT hr = S_OK; AbstractDeviceContent* pContent = NULL; if ((wszObjectID == NULL) || (pAttributes == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } hr = GetContent(Scope, wszObjectID, &pContent); CHECK_HR(hr, "Failed to get content '%ws'", wszObjectID); if (hr == S_OK) { hr = pContent->GetPropertyAttributes(Key, pAttributes); CHECK_HR(hr, "Failed to get property attributes for '%ws'", wszObjectID); } return hr; }
HRESULT BthLEDevice::GetPropertyValues( ACCESS_SCOPE Scope, _In_ LPCWSTR wszObjectID, _In_ IPortableDeviceKeyCollection* pKeys, _Inout_ IPortableDeviceValues* pValues) { HRESULT hrReturn = S_OK; HRESULT hr = S_OK; DWORD cKeys = 0; AbstractDeviceContent* pContent = NULL; if ((wszObjectID == NULL) || (pKeys == NULL) || (pValues == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } hr = GetContent(Scope, wszObjectID, &pContent); CHECK_HR(hr, "Failed to get content '%ws'", wszObjectID); if (hr == S_OK) { hr = pKeys->GetCount(&cKeys); CHECK_HR(hr, "Failed to number of PROPERTYKEYs in collection"); } if (hr == S_OK) { for (DWORD dwIndex = 0; dwIndex < cKeys; dwIndex++) { PROPERTYKEY Key = WPD_PROPERTY_NULL; hr = pKeys->GetAt(dwIndex, &Key); CHECK_HR(hr, "Failed to get PROPERTYKEY at index %d in collection", dwIndex); if (hr == S_OK) { hr = pContent->GetValue(Key, pValues); CHECK_HR(hr, "Failed to get property at index %d", dwIndex); if (FAILED(hr)) { // Mark the property as failed by setting the error value // hrReturn is marked as S_FALSE indicating that at least one property has failed. hr = pValues->SetErrorValue(Key, hr); hrReturn = S_FALSE; } } } } if (FAILED(hr)) { // A general error has occurred (rather than failure to set one or more properties) hrReturn = hr; } return hrReturn; }
HRESULT BthLEDevice::GetSupportedProperties( ACCESS_SCOPE Scope, _In_ LPCWSTR wszObjectID, _Inout_ IPortableDeviceKeyCollection* pKeys) { HRESULT hr = S_OK; AbstractDeviceContent* pContent = NULL; if ((wszObjectID == NULL) || (pKeys == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } hr = GetContent(Scope, wszObjectID, &pContent); CHECK_HR(hr, "Failed to get content '%ws'", wszObjectID); if (hr == S_OK) { hr = pContent->GetSupportedProperties(pKeys); CHECK_HR(hr, "Failed to get supported properties for '%ws'", wszObjectID); } return hr; }
HRESULT BthLEDevice::GetObjectIDsByFormat( ACCESS_SCOPE Scope, REFGUID guidObjectFormat, _In_ LPCWSTR wszParentObjectID, const DWORD dwDepth, _Inout_ IPortableDevicePropVariantCollection* pObjectIDs) { HRESULT hr = S_OK; AbstractDeviceContent* pContent = NULL; if(pObjectIDs == NULL) { hr = E_POINTER; CHECK_HR(hr, ("Cannot have NULL parameter")); return hr; } hr = GetContent(Scope, wszParentObjectID, &pContent); CHECK_HR(hr, "Failed to get content '%ws'", wszParentObjectID); if (hr == S_OK) { hr = pContent->GetObjectIDsByFormat(Scope, guidObjectFormat, dwDepth, pObjectIDs); CHECK_HR(hr, "Failed to get object IDs by format"); } return hr; }
HRESULT AbstractDeviceContent::GetObjectIDByPersistentID( ACCESS_SCOPE Scope, _In_ LPCWSTR wszPersistentID, _Out_ IPortableDevicePropVariantCollection* pObjectIDs) { HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); CComCritSecLock<CComAutoCriticalSection> Lock(m_ChildrenCS); if (CanAccess(Scope)) { if (PersistentUniqueID.CompareNoCase(wszPersistentID) == 0) { PROPVARIANT pv = {0}; PropVariantInit(&pv); pv.vt = VT_LPWSTR; pv.pwszVal = ObjectID.GetBuffer(); hr = pObjectIDs->Add(&pv); CHECK_HR(hr, "Failed to add '%ws' to the list of object IDs", ObjectID); } else { DWORD dwIndex = 0; AbstractDeviceContent* pChild = NULL; while (FindNext(Scope, dwIndex, &pChild)) { hr = pChild->GetObjectIDByPersistentID(Scope, wszPersistentID, pObjectIDs); if (hr == S_OK || hr == E_ACCESSDENIED) { // Found the object or was denied access break; } else if (hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) { CHECK_HR(hr, "Failed to get object ID for child at index %d", dwIndex); } dwIndex++; } } } else { hr = E_ACCESSDENIED; } return hr; }
HRESULT AbstractDeviceContent::GetObjectIDsByFormat( ACCESS_SCOPE Scope, REFGUID guidFormat, const DWORD dwDepth, _Inout_ IPortableDevicePropVariantCollection* pObjectIDs) { HRESULT hr = S_OK; CComCritSecLock<CComAutoCriticalSection> Lock(m_ChildrenCS); if (CanAccess(Scope)) { DWORD dwIndex = 0; AbstractDeviceContent* pChild = NULL; if (Format == guidFormat || guidFormat == WPD_OBJECT_FORMAT_ALL) { PROPVARIANT pv = {0}; PropVariantInit(&pv); pv.vt = VT_LPWSTR; pv.pwszVal = ObjectID.GetBuffer(); hr = pObjectIDs->Add(&pv); CHECK_HR(hr, "Failed to add '%ws' to the list of object IDs by format", ObjectID); } if (dwDepth > 0) { while ((hr == S_OK) && (FindNext(Scope, dwIndex, &pChild))) { hr = pChild->GetObjectIDsByFormat(Scope, guidFormat, dwDepth-1, pObjectIDs); CHECK_HR(hr, "Failed to get object IDs by format for child at index %d", dwIndex); dwIndex++; } } } else { hr = E_ACCESSDENIED; } return hr; }
HRESULT AbstractDeviceContent::GetContent( ACCESS_SCOPE Scope, _In_ LPCWSTR wszObjectID, _Out_ AbstractDeviceContent** ppContent) { HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); CComCritSecLock<CComAutoCriticalSection> Lock(m_ChildrenCS); if (CanAccess(Scope)) { if (ObjectID.CompareNoCase(wszObjectID) == 0) { hr = S_OK; *ppContent = this; } else { DWORD dwIndex = 0; AbstractDeviceContent* pChild = NULL; while (FindNext(Scope, dwIndex, &pChild)) { hr = pChild->GetContent(Scope, wszObjectID, ppContent); if (hr == S_OK || hr == E_ACCESSDENIED) { break; } dwIndex++; } } } else { hr = E_ACCESSDENIED; CHECK_HR(hr, "GetContent: '%ws' was found but falls outside scope", wszObjectID); } return hr; }
void BthLEDevice::InitializeEnumerationContext( ACCESS_SCOPE Scope, _In_ LPCWSTR wszParentID, _Out_ WpdObjectEnumeratorContext* pEnumContext) { if (pEnumContext == NULL) { return; } pEnumContext->m_Scope = Scope; pEnumContext->m_strParentObjectID = wszParentID; if (pEnumContext->m_strParentObjectID.GetLength() == 0) { // Clients passing an 'empty' string for the parent are asking for the // 'DEVICE' object. We should return 1 child in this case. pEnumContext->m_TotalChildren = 1; } else { AbstractDeviceContent* pContent = NULL; HRESULT hr = GetContent(Scope, wszParentID, &pContent); if (hr == S_OK) { hr = pContent->InitializeEnumerationContext(Scope, pEnumContext); CHECK_HR(hr, "Failed to initialize enuemration context for '%ws'", wszParentID); } if (hr != S_OK) { // Invalid, or non-existing objects contain no children. pEnumContext->m_TotalChildren = 0; } } }
HRESULT BthLEDevice::FindNext( const DWORD dwNumObjectsRequested, _In_ WpdObjectEnumeratorContext* pEnumContext, _Inout_ IPortableDevicePropVariantCollection* pObjectIDCollection, _Out_ DWORD* pdwNumObjectsEnumerated) { HRESULT hr = S_OK; DWORD NumObjectsEnumerated = 0; if ((pEnumContext == NULL) || (pObjectIDCollection == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } if (NULL != pdwNumObjectsEnumerated) { *pdwNumObjectsEnumerated = 0; } // If the enumeration context reports that their are more objects to return, then continue, if not, // return an empty results set. if (pEnumContext->HasMoreChildrenToEnumerate()) { if (pEnumContext->m_strParentObjectID.CompareNoCase(L"") == 0) { // We are being asked for the device hr = AddStringValueToPropVariantCollection(pObjectIDCollection, m_DeviceContent.ObjectID); CHECK_HR(hr, "Failed to add 'DEVICE' object ID to enumeration collection"); // Update the the number of children we are returning for this enumeration call NumObjectsEnumerated++; } else { AbstractDeviceContent* pContent = NULL; HRESULT hrGet = GetContent(pEnumContext->m_Scope, pEnumContext->m_strParentObjectID, &pContent); CHECK_HR(hrGet, "Failed to get content '%ws'", pEnumContext->m_strParentObjectID); if (hrGet == S_OK) { DWORD dwStartIndex = pEnumContext->m_ChildrenEnumerated; for (DWORD i=0; i<dwNumObjectsRequested; i++) { AbstractDeviceContent* pChild = NULL; if (pContent->FindNext(pEnumContext->m_Scope, dwStartIndex, &pChild)) { hr = AddStringValueToPropVariantCollection(pObjectIDCollection, pChild->ObjectID); CHECK_HR(hr, "Failed to add object [%ws]", pChild->ObjectID); if (hr == S_OK) { // Update the the number of children we are returning for this enumeration call dwStartIndex++; NumObjectsEnumerated++; } } else { // no more children break; } } } } } if (hr == S_OK && pdwNumObjectsEnumerated) { *pdwNumObjectsEnumerated = NumObjectsEnumerated; } return hr; }