summaryrefslogtreecommitdiff
path: root/wpd/WpdServiceSampleDriver/FakeDevice.cpp
diff options
context:
space:
mode:
authorAdonais Romero González <[email protected]>2024-05-06 16:21:31 -0700
committerGitHub <[email protected]>2024-05-06 16:21:31 -0700
commita74a241c664c4e1d7c0838287b34076c19d9858a (patch)
tree6ff7562612967b122acf8acf8a69c4dcfd5905db /wpd/WpdServiceSampleDriver/FakeDevice.cpp
parentdef8e8e34ed2b7b1deb2fc9112ac4255f1a0f2ba (diff)
parent15477ce52bbb6b42ca591ecdfb484cac089f89ab (diff)
Merge develop changes prior to upcoming WDK release (May 2024)
Diffstat (limited to 'wpd/WpdServiceSampleDriver/FakeDevice.cpp')
-rw-r--r--wpd/WpdServiceSampleDriver/FakeDevice.cpp1122
1 files changed, 0 insertions, 1122 deletions
diff --git a/wpd/WpdServiceSampleDriver/FakeDevice.cpp b/wpd/WpdServiceSampleDriver/FakeDevice.cpp
deleted file mode 100644
index d5f8d4d4..00000000
--- a/wpd/WpdServiceSampleDriver/FakeDevice.cpp
+++ /dev/null
@@ -1,1122 +0,0 @@
-#include "stdafx.h"
-
-#include "FakeDevice.tmh"
-
-const PROPERTYKEY* g_SupportedCommands[] =
-{
- // WPD_CATEGORY_OBJECT_ENUMERATION
- &WPD_COMMAND_OBJECT_ENUMERATION_START_FIND,
- &WPD_COMMAND_OBJECT_ENUMERATION_FIND_NEXT,
- &WPD_COMMAND_OBJECT_ENUMERATION_END_FIND,
-
- // WPD_CATEGORY_OBJECT_PROPERTIES
- &WPD_COMMAND_OBJECT_PROPERTIES_GET_SUPPORTED,
- &WPD_COMMAND_OBJECT_PROPERTIES_GET,
- &WPD_COMMAND_OBJECT_PROPERTIES_GET_ALL,
- &WPD_COMMAND_OBJECT_PROPERTIES_SET,
- &WPD_COMMAND_OBJECT_PROPERTIES_GET_ATTRIBUTES,
- &WPD_COMMAND_OBJECT_PROPERTIES_DELETE,
-
- // WPD_CATEGORY_OBJECT_RESOURCES
- &WPD_COMMAND_OBJECT_RESOURCES_GET_SUPPORTED,
- &WPD_COMMAND_OBJECT_RESOURCES_OPEN,
- &WPD_COMMAND_OBJECT_RESOURCES_READ,
- &WPD_COMMAND_OBJECT_RESOURCES_CLOSE,
- &WPD_COMMAND_OBJECT_RESOURCES_GET_ATTRIBUTES,
-
- // WPD_CATEGORY_CAPABILITIES
- &WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_COMMANDS,
- &WPD_COMMAND_CAPABILITIES_GET_COMMAND_OPTIONS,
- &WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_FUNCTIONAL_CATEGORIES,
- &WPD_COMMAND_CAPABILITIES_GET_FUNCTIONAL_OBJECTS,
- &WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_CONTENT_TYPES,
- &WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_FORMATS,
- &WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_FORMAT_PROPERTIES,
- &WPD_COMMAND_CAPABILITIES_GET_FIXED_PROPERTY_ATTRIBUTES,
-
- // WPD_CATEGORY_OBJECT_MANAGEMENT
- &WPD_COMMAND_OBJECT_MANAGEMENT_CREATE_OBJECT_WITH_PROPERTIES_ONLY,
- &WPD_COMMAND_OBJECT_MANAGEMENT_DELETE_OBJECTS,
-
- // WPD_CATEGORY_OBJECT_PROPERTIES_BULK
- &WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_LIST_START,
- &WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_LIST_NEXT,
- &WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_LIST_END,
- &WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_START,
- &WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_NEXT,
- &WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_END,
- &WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_START,
- &WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_NEXT,
- &WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_END,
-
- // WPD_CATEGORY_COMMON
- &WPD_COMMAND_COMMON_GET_OBJECT_IDS_FROM_PERSISTENT_UNIQUE_IDS,
-};
-
-
-const GUID* g_SupportedFunctionalCategories[] =
-{
- &WPD_FUNCTIONAL_CATEGORY_DEVICE,
- &WPD_FUNCTIONAL_CATEGORY_STORAGE,
- &SERVICE_Contacts,
-};
-
-const PROPERTYKEY* g_SupportedCommonProperties[] =
-{
- &WPD_OBJECT_ID,
- &WPD_OBJECT_PERSISTENT_UNIQUE_ID,
- &WPD_OBJECT_PARENT_ID,
- &WPD_OBJECT_NAME,
- &WPD_OBJECT_FORMAT,
- &WPD_OBJECT_CONTENT_TYPE,
- &WPD_OBJECT_CAN_DELETE,
- &WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID,
-};
-
-
-HRESULT FakeDevice::InitializeContent()
-{
- HRESULT hr = m_DeviceContent.InitializeContent(&m_dwLastObjectID);
- CHECK_HR(hr, "Failed to initialize device content");
- return hr;
-}
-
-FakeContactsService* FakeDevice::GetContactsService()
-{
- return &m_ContactsService;
-}
-
-ACCESS_SCOPE FakeDevice::GetAccessScope(
- _In_ IPortableDeviceValues* pParams)
-{
- ACCESS_SCOPE Scope = FULL_DEVICE_ACCESS;
- LPWSTR pszFileName = NULL;
-
- // For simplicity, our request filename is the same as the the service object ID
- if (pParams && (pParams->GetStringValue(PRIVATE_SAMPLE_DRIVER_REQUEST_FILENAME, &pszFileName) == S_OK))
- {
- CAtlStringW strRequestFilename = pszFileName;
- // For simplicity, our request filename is the same as the the service object ID
- // Case-insensitive comparison is required
- if (strRequestFilename.CompareNoCase(m_ContactsService.GetRequestFilename()) == 0)
- {
- Scope = CONTACTS_SERVICE_ACCESS;
- }
- }
-
- CoTaskMemFree(pszFileName);
- return Scope;
-}
-
-HRESULT FakeDevice::GetSupportedCommands(
- _In_ IPortableDeviceKeyCollection* pCommands)
-{
- HRESULT hr = S_OK;
-
- if(pCommands == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
-
- for (DWORD dwIndex = 0; dwIndex < ARRAYSIZE(g_SupportedCommands); dwIndex++)
- {
- PROPERTYKEY key = *(g_SupportedCommands[dwIndex]);
- hr = pCommands->Add(key);
- CHECK_HR(hr, "Failed to add supported command at index %d", dwIndex);
- if (FAILED(hr))
- {
- break;
- }
- }
- return hr;
-}
-
-HRESULT FakeDevice::GetCommandOptions(
- _In_ REFPROPERTYKEY Command,
- _In_ IPortableDeviceValues* pOptions)
-{
- HRESULT hr = S_OK;
-
- if(pOptions == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
-
- // Check for command options
- if (IsEqualPropertyKey(WPD_COMMAND_OBJECT_MANAGEMENT_DELETE_OBJECTS, Command))
- {
- // This driver does not support recursive deletion
- hr = pOptions->SetBoolValue(WPD_OPTION_OBJECT_MANAGEMENT_RECURSIVE_DELETE_SUPPORTED, TRUE);
- CHECK_HR(hr, "Failed to set WPD_OPTION_OBJECT_MANAGEMENT_RECURSIVE_DELETE_SUPPORTED");
- }
- if (IsEqualPropertyKey(WPD_COMMAND_OBJECT_RESOURCES_READ, Command))
- {
- // For better read performance, tell the API not to provide the input buffer parameter
- // when issuing a WPD_COMMAND_OBJECT_RESOURCES_READ command.
- hr = pOptions->SetBoolValue(WPD_OPTION_OBJECT_RESOURCES_NO_INPUT_BUFFER_ON_READ, TRUE);
- CHECK_HR(hr, "Failed to set WPD_OPTION_OBJECT_RESOURCES_NO_INPUT_BUFFER_ON_READ");
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetSupportedFunctionalCategories(
- _In_ IPortableDevicePropVariantCollection* pFunctionalCategories)
-{
- HRESULT hr = S_OK;
-
- if(pFunctionalCategories == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
-
- // Device-wide command
- for (DWORD dwIndex = 0; dwIndex < ARRAYSIZE(g_SupportedFunctionalCategories); dwIndex++)
- {
- PROPVARIANT pv = {0};
- PropVariantInit(&pv);
- // Don't call PropVariantClear, since we did not allocate the memory for these GUIDs
-
- pv.vt = VT_CLSID;
- pv.puuid = (CLSID*)g_SupportedFunctionalCategories[dwIndex];
-
- hr = pFunctionalCategories->Add(&pv);
- CHECK_HR(hr, "Failed to add supported functional category at index %d", dwIndex);
- if (FAILED(hr))
- {
- break;
- }
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetFunctionalObjects(
- _In_ REFGUID guidFunctionalCategory,
- _In_ IPortableDevicePropVariantCollection* pFunctionalObjects)
-{
- HRESULT hr = S_OK;
- PROPVARIANT pv = {0};
-
- if(pFunctionalObjects == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
-
- PropVariantInit(&pv);
- // Don't call PropVariantClear, since we did not allocate the memory for these object identifiers
-
- // Add WPD_DEVICE_OBJECT_ID to the functional object identifiers collection
- if ((guidFunctionalCategory == WPD_FUNCTIONAL_CATEGORY_DEVICE) ||
- (guidFunctionalCategory == WPD_FUNCTIONAL_CATEGORY_ALL))
- {
- pv.vt = VT_LPWSTR;
- pv.pwszVal = WPD_DEVICE_OBJECT_ID;
- hr = pFunctionalObjects->Add(&pv);
- CHECK_HR(hr, "Failed to add device object ID");
- }
-
- // Add CONTACTS_SERVICE_OBJECT_ID to the functional object identifiers collection
- if (hr == S_OK)
- {
- if ((guidFunctionalCategory == SERVICE_Contacts) ||
- (guidFunctionalCategory == WPD_FUNCTIONAL_CATEGORY_ALL))
- {
- pv.vt = VT_LPWSTR;
- pv.pwszVal = CONTACTS_SERVICE_OBJECT_ID;
- hr = pFunctionalObjects->Add(&pv);
- CHECK_HR(hr, "Failed to add contacts service object ID");
- }
- }
-
- // Add STORAGE_OBJECT_ID to the functional object identifiers collection
- // if request is not scoped by the contacts service
- if ((guidFunctionalCategory == WPD_FUNCTIONAL_CATEGORY_STORAGE) ||
- (guidFunctionalCategory == WPD_FUNCTIONAL_CATEGORY_ALL))
- {
- pv.vt = VT_LPWSTR;
- pv.pwszVal = STORAGE_OBJECT_ID;
- hr = pFunctionalObjects->Add(&pv);
- CHECK_HR(hr, "Failed to add storage object ID");
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetSupportedContentTypes(
- _In_ REFGUID guidFunctionalCategory,
- _In_ IPortableDevicePropVariantCollection* pContentTypes)
-{
- HRESULT hr = S_OK;
-
- if(pContentTypes == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
-
- PROPVARIANT pv = {0};
- PropVariantInit(&pv);
- // Don't call PropVariantClear, since we did not allocate the memory for these GUIDs
-
- // Add supported content types for known functional categories
- if (guidFunctionalCategory == WPD_FUNCTIONAL_CATEGORY_STORAGE)
- {
- // Add WPD_CONTENT_TYPE_DOCUMENT to the supported content type collection
- pv.vt = VT_CLSID;
- pv.puuid = (CLSID*)&WPD_CONTENT_TYPE_DOCUMENT;
- hr = pContentTypes->Add(&pv);
- CHECK_HR(hr, "Failed to add WPD_CONTENT_TYPE_DOCUMENT");
-
- if (hr == S_OK)
- {
- // Add WPD_CONTENT_TYPE_FOLDER to the supported content type collection
- pv.vt = VT_CLSID;
- pv.puuid = (CLSID*)&WPD_CONTENT_TYPE_FOLDER;
- hr = pContentTypes->Add(&pv);
- CHECK_HR(hr, "Failed to add WPD_CONTENT_TYPE_FOLDER");
- }
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetSupportedFormats(
- _In_ REFGUID guidContentType,
- _In_ IPortableDevicePropVariantCollection* pFormats)
-{
- HRESULT hr = S_OK;
-
- if(pFormats == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
-
- PROPVARIANT pv = {0};
- PropVariantInit(&pv);
- pv.vt = VT_CLSID;
-
- // Don't call PropVariantClear, since we did not allocate the memory for these GUIDs
-
- if ((guidContentType == WPD_CONTENT_TYPE_CONTACT) ||
- (guidContentType == WPD_CONTENT_TYPE_ALL))
- {
- pv.puuid = (CLSID*)&FORMAT_AbstractContact;
- hr = pFormats->Add(&pv);
- CHECK_HR(hr, "Failed to add FORMAT_AbstractContact");
-
- pv.puuid = (CLSID*)&FORMAT_VCard2Contact;
- hr = pFormats->Add(&pv);
- CHECK_HR(hr, "Failed to add FORMAT_VCard2Contact");
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetSupportedFormatProperties(
- _In_ REFGUID guidObjectFormat,
- _In_ IPortableDeviceKeyCollection* pKeys)
-{
- HRESULT hr = S_OK;
-
- if(pKeys == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
-
- if (guidObjectFormat == WPD_OBJECT_FORMAT_ALL)
- {
- for (DWORD dwIndex = 0; dwIndex < ARRAYSIZE(g_SupportedCommonProperties); dwIndex++)
- {
- PROPERTYKEY key = *g_SupportedCommonProperties[dwIndex];
- hr = pKeys->Add(key);
- CHECK_HR(hr, "Failed to add common property");
- }
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetFixedPropertyAttributes(
- _In_ REFGUID guidObjectFormat,
- _In_ REFPROPERTYKEY Key,
- _In_ IPortableDeviceValues* pAttributes)
-{
- UNREFERENCED_PARAMETER(guidObjectFormat);
- UNREFERENCED_PARAMETER(Key);
-
- HRESULT hr = S_OK;
-
- if(pAttributes == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
-
- //
- // Since ALL of our properties have the same attributes, we are ignoring the
- // passed in guidObjectFormat and Key parameters. These parameters allow you to
- // customize fixed property attributes for properties for specific formats.
- //
-
- if (hr == S_OK)
- {
- hr = pAttributes->SetBoolValue(WPD_PROPERTY_ATTRIBUTE_CAN_DELETE, FALSE);
- CHECK_HR(hr, "Failed to set WPD_PROPERTY_ATTRIBUTE_CAN_DELETE");
- }
-
- if (hr == S_OK)
- {
- hr = pAttributes->SetBoolValue(WPD_PROPERTY_ATTRIBUTE_CAN_READ, TRUE);
- CHECK_HR(hr, "Failed to set WPD_PROPERTY_ATTRIBUTE_CAN_READ");
- }
-
- if (hr == S_OK)
- {
- hr = pAttributes->SetBoolValue(WPD_PROPERTY_ATTRIBUTE_CAN_WRITE, FALSE);
- CHECK_HR(hr, "Failed to set WPD_PROPERTY_ATTRIBUTE_CAN_WRITE");
- }
-
- if (hr == S_OK)
- {
- hr = pAttributes->SetBoolValue(WPD_PROPERTY_ATTRIBUTE_FAST_PROPERTY, TRUE);
- CHECK_HR(hr, "Failed to set WPD_PROPERTY_ATTRIBUTE_FAST_PROPERTY");
- }
-
- if (hr == S_OK)
- {
- hr = pAttributes->SetUnsignedIntegerValue(WPD_PROPERTY_ATTRIBUTE_FORM, WPD_PROPERTY_ATTRIBUTE_FORM_UNSPECIFIED);
- CHECK_HR(hr, "Failed to set WPD_PROPERTY_ATTRIBUTE_FORM");
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetSupportedEvents(
- _In_ IPortableDevicePropVariantCollection* pEvents)
-{
- UNREFERENCED_PARAMETER(pEvents);
-
- HRESULT hr = S_OK;
-
- if(pEvents == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
- return hr;
-}
-
-HRESULT FakeDevice::GetEventOptions(
- _In_ IPortableDeviceValues* pOptions)
-{
- UNREFERENCED_PARAMETER(pOptions);
-
- HRESULT hr = S_OK;
-
- if(pOptions == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
- return hr;
-}
-
-void FakeDevice::InitializeEnumerationContext(
- ACCESS_SCOPE Scope,
- _In_ LPCWSTR wszParentID,
- _In_ 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
- {
- FakeContent* 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 FakeDevice::FindNext(
- const DWORD dwNumObjectsRequested,
- _In_ WpdObjectEnumeratorContext* pEnumContext,
- _In_ IPortableDevicePropVariantCollection* pObjectIDCollection,
- _Out_opt_ 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 (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
- {
- FakeContent* 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++)
- {
- FakeContent* 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;
-}
-
-HRESULT FakeDevice::GetObjectIDsByFormat(
- ACCESS_SCOPE Scope,
- _In_ REFGUID guidObjectFormat,
- _In_ LPCWSTR wszParentObjectID,
- const DWORD dwDepth,
- _In_ IPortableDevicePropVariantCollection* pObjectIDs)
-{
- HRESULT hr = S_OK;
- FakeContent* 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 FakeDevice::GetObjectIDsFromPersistentUniqueIDs(
- ACCESS_SCOPE Scope,
- _In_ IPortableDevicePropVariantCollection* pPersistentIDs,
- _In_ IPortableDevicePropVariantCollection* pObjectIDs)
-{
- HRESULT hr = S_OK;
- DWORD dwCount = 0;
-
- if ((pPersistentIDs == NULL) ||
- (pObjectIDs == NULL))
- {
- hr = E_POINTER;
- CHECK_HR(hr, ("Cannot have NULL parameter"));
- return hr;
- }
-
- // Iterate through the persistent ID list and add the equivalent object ID for each element.
- hr = pPersistentIDs->GetCount(&dwCount);
- CHECK_HR(hr, "Failed to get count from persistent ID collection");
-
- if (hr == S_OK)
- {
- PROPVARIANT pvPersistentID = {0};
-
- for(DWORD dwIndex = 0; dwIndex < dwCount; dwIndex++)
- {
- PropVariantInit(&pvPersistentID);
-
- hr = pPersistentIDs->GetAt(dwIndex, &pvPersistentID);
- CHECK_HR(hr, "Failed to get persistent ID at index %d", dwIndex);
-
- if (hr == S_OK)
- {
- hr = m_DeviceContent.GetObjectIDByPersistentID(Scope, pvPersistentID.pwszVal, pObjectIDs);
- CHECK_HR(hr, "Failed to get object ID from persistent unique ID '%ws'", pvPersistentID.pwszVal);
- }
-
- if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
- {
- PROPVARIANT pvEmptyObjectID = {0};
- pvEmptyObjectID.vt = VT_LPWSTR;
- pvEmptyObjectID.pwszVal = L"";
-
- // Insert empty string when object cannot be found
- hr = pObjectIDs->Add(&pvEmptyObjectID);
- CHECK_HR(hr, "Failed to set empty string for persistent unique ID '%ws' when object cannot be found", pvPersistentID.pwszVal);
- }
-
- PropVariantClear(&pvPersistentID);
-
- if(FAILED(hr))
- {
- break;
- }
- }
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetSupportedProperties(
- ACCESS_SCOPE Scope,
- _In_ LPCWSTR wszObjectID,
- _In_ IPortableDeviceKeyCollection* pKeys)
-{
- HRESULT hr = S_OK;
- FakeContent* 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 FakeDevice::GetAllPropertyValues(
- ACCESS_SCOPE Scope,
- _In_ LPCWSTR wszObjectID,
- _In_ IPortableDeviceValues* pValues)
-{
- HRESULT hr = S_OK;
- FakeContent* pContent = NULL;
-
- if ((wszObjectID == 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 = pContent->GetAllValues(pValues);
- CHECK_HR(hr, "Failed to get all property values for '%ws'", wszObjectID);
- }
- return hr;
-}
-
-
-HRESULT FakeDevice::GetPropertyValues(
- ACCESS_SCOPE Scope,
- _In_ LPCWSTR wszObjectID,
- _In_ IPortableDeviceKeyCollection* pKeys,
- _In_ IPortableDeviceValues* pValues)
-{
- HRESULT hrReturn = S_OK;
- HRESULT hr = S_OK;
- DWORD cKeys = 0;
- FakeContent* 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 FakeDevice::SetPropertyValues(
- ACCESS_SCOPE Scope,
- _In_ LPCWSTR wszObjectID,
- _In_ IPortableDeviceValues* pValues,
- _In_ IPortableDeviceValues* pResults,
- _In_ IPortableDeviceValues* pEventParams,
- _Out_ bool* pbObjectChanged)
-{
- HRESULT hr = S_OK;
- FakeContent* 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 FakeDevice::GetPropertyAtributes(
- ACCESS_SCOPE Scope,
- _In_ LPCWSTR wszObjectID,
- _In_ REFPROPERTYKEY Key,
- _In_ IPortableDeviceValues* pAttributes)
-{
- HRESULT hr = S_OK;
- FakeContent* 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 FakeDevice::CreatePropertiesOnlyObject(
- ACCESS_SCOPE Scope,
- _In_ IPortableDeviceValues* pObjectProperties,
- _In_ IPortableDeviceValues* pEventParams,
- _Outptr_result_nullonfailure_ LPWSTR* ppszNewObjectID)
-{
- HRESULT hr;
- LPWSTR pszParentID = NULL;
- FakeContent* pParent = NULL;
- FakeContent* pNewObject = NULL;
-
- if ((pObjectProperties == NULL) ||
- (pEventParams == NULL) ||
- (ppszNewObjectID == NULL))
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- return hr;
- }
-
- *ppszNewObjectID = NULL;
-
- // Get WPD_OBJECT_PARENT_ID
- hr = pObjectProperties->GetStringValue(WPD_OBJECT_PARENT_ID, &pszParentID);
- CHECK_HR(hr, "Failed to get WPD_OBJECT_PARENT_ID");
-
- // Check if it is within our current access scope
- if (SUCCEEDED(hr))
- {
- hr = GetContent(Scope, pszParentID, &pParent);
- CHECK_HR(hr, "Failed to get content '%ws'", pszParentID);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = pParent->CreatePropertiesOnlyObject(pObjectProperties, &m_dwLastObjectID, &pNewObject);
- CHECK_HR(hr, "Failed to create properties only object with parent '%ws'", pszParentID);
- }
-
- if (SUCCEEDED(hr))
- {
- *ppszNewObjectID = AtlAllocTaskWideString(pNewObject->ObjectID);
- if (*ppszNewObjectID == NULL)
- {
- hr = E_OUTOFMEMORY;
- CHECK_HR(hr, "Failed to allocate memory for created object ID");
- }
-
- HRESULT hrEvent = pEventParams->SetGuidValue(WPD_EVENT_PARAMETER_EVENT_ID, WPD_EVENT_OBJECT_ADDED);
- CHECK_HR(hrEvent, "Failed to add WPD_EVENT_PARAMETER_EVENT_ID");
-
- if (hrEvent == S_OK)
- {
- hrEvent = pEventParams->SetStringValue(WPD_OBJECT_PERSISTENT_UNIQUE_ID, pNewObject->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, pNewObject->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, pNewObject->ContainerFunctionalObjectID);
- CHECK_HR(hrEvent, "Failed to add WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID");
- }
- }
-
- CoTaskMemFree(pszParentID);
- return hr;
-}
-
-HRESULT FakeDevice::DeleteObject(
- ACCESS_SCOPE Scope,
- const DWORD dwDeleteOptions,
- _In_ LPCWSTR wszObjectID,
- _In_ IPortableDeviceValues* pEventParams)
-{
- HRESULT hr = S_OK;
- FakeContent* pContent = NULL;
-
- if ((wszObjectID == NULL) ||
- (pEventParams == 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->MarkForDelete(dwDeleteOptions);
- CHECK_HR(hr, "Failed to mark '%ws' for delete with option %d", wszObjectID, dwDeleteOptions);
- }
-
- if (hr == S_OK)
- {
- HRESULT hrEvent = pEventParams->SetGuidValue(WPD_EVENT_PARAMETER_EVENT_ID, WPD_EVENT_OBJECT_REMOVED);
- 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");
- }
-
- hr = m_DeviceContent.RemoveObjectsMarkedForDeletion(Scope);
- CHECK_HR(hr, "Failed to remove all objects marked for deletion");
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetSupportedResources(
- ACCESS_SCOPE Scope,
- _In_ LPCWSTR wszObjectID,
- _In_ IPortableDeviceKeyCollection* pResources)
-{
- HRESULT hr = S_OK;
- FakeContent* pContent = NULL;
-
- if ((wszObjectID == NULL) ||
- (pResources == 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->GetSupportedResources(pResources);
- CHECK_HR(hr, "Failed to get the supported resources for '%ws'", wszObjectID);
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetResourceAttributes(
- ACCESS_SCOPE Scope,
- _In_ LPCWSTR wszObjectID,
- _In_ REFPROPERTYKEY Resource,
- _In_ IPortableDeviceValues* pAttributes)
-{
- HRESULT hr = S_OK;
- FakeContent* 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->GetResourceAttributes(Resource, pAttributes);
- CHECK_HR(hr, "Failed to get the supported resources for '%ws'", wszObjectID);
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::OpenResource(
- ACCESS_SCOPE Scope,
- _In_ LPCWSTR wszObjectID,
- _In_ REFPROPERTYKEY Resource,
- const DWORD dwMode,
- _In_ WpdObjectResourceContext* pResourceContext)
-{
- HRESULT hr = S_OK;
- FakeContent* pContent = NULL;
-
- if ((wszObjectID == NULL) ||
- (pResourceContext == 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)
- {
- pResourceContext->m_Scope = Scope;
- hr = pContent->OpenResource(Resource, dwMode, pResourceContext);
- CHECK_HR(hr, "Failed to open resource for '%ws'", wszObjectID);
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::ReadResourceData(
- _In_ WpdObjectResourceContext* pResourceContext,
- _Out_writes_to_(dwNumBytesToRead, *pdwNumBytesRead) BYTE* pBuffer,
- const DWORD dwNumBytesToRead,
- _Out_ DWORD* pdwNumBytesRead)
-{
- HRESULT hr = S_OK;
- FakeContent* pContent = NULL;
-
- if ((pResourceContext == NULL) ||
- (pBuffer == NULL) ||
- (pdwNumBytesRead == NULL))
- {
- hr = E_INVALIDARG;
- return hr;
- }
-
- *pdwNumBytesRead = 0;
-
- hr = GetContent(pResourceContext->m_Scope, pResourceContext->m_strObjectID, &pContent);
- CHECK_HR(hr, "Failed to get content '%ws'", pResourceContext->m_strObjectID);
-
- if (hr == S_OK)
- {
- hr = pContent->ReadResourceData(pResourceContext, pBuffer, dwNumBytesToRead, pdwNumBytesRead);
- CHECK_HR(hr, "Failed to read resource data for '%ws'", pResourceContext->m_strObjectID);
- }
-
- return hr;
-}
-
-HRESULT FakeDevice::GetContent(
- ACCESS_SCOPE Scope,
- _In_ LPCWSTR wszObjectID,
- _Outptr_result_nullonfailure_ FakeContent** ppContent)
-{
- HRESULT hr = S_OK;
-
- if (ppContent == NULL)
- {
- hr = E_POINTER;
- CHECK_HR(hr, "Cannot have NULL parameter");
- }
-
- *ppContent = NULL;
-
- hr = m_DeviceContent.GetContent(Scope, wszObjectID, ppContent);
- CHECK_HR(hr, "Failed to get content '%ws'", wszObjectID);
-
- return hr;
-}