HRESULT WpdObjectEnumerator::CreateEnumContext( __inout ContextMap* pContextMap, __in LPCWSTR pszParentID, __deref_out_opt LPWSTR* ppszEnumContext) { HRESULT hr = S_OK; GUID guidContext = GUID_NULL; CComBSTR bstrContext; EnumContext* pContext = NULL; if((pContextMap == NULL) || (pszParentID == NULL) || (ppszEnumContext == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } *ppszEnumContext = NULL; hr = CoCreateGuid(&guidContext); if (hr == S_OK) { bstrContext = guidContext; if(bstrContext.Length() == 0) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to create BSTR from GUID"); } } if (hr == S_OK) { pContext = new EnumContext(); if(pContext != NULL) { CAtlStringW strKey = bstrContext; pContext->ParentID = pszParentID; hr = pContextMap->Add(strKey, pContext); CHECK_HR(hr, "Failed to add enumeration context to client context map"); pContext->Release(); } else { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate enumeration context"); } } if (hr == S_OK) { *ppszEnumContext = AtlAllocTaskWideString(bstrContext); } return hr; }
HRESULT WpdObjectPropertiesBulk::CreateBulkPropertiesContext( __in ACCESS_SCOPE Scope, __inout ContextMap* pContextMap, __in IPortableDevicePropVariantCollection* pObjectIDs, __in IPortableDeviceKeyCollection* pProperties, __deref_out_opt LPWSTR* ppszBulkPropertiesContext) { HRESULT hr = S_OK; BulkPropertiesContext* pContext = NULL; CAtlStringW strKey; if((pContextMap == NULL) || (pObjectIDs == NULL) || (ppszBulkPropertiesContext == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } *ppszBulkPropertiesContext = NULL; if (hr == S_OK) { pContext = new BulkPropertiesContext(); if(pContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate new bulk properties context"); } } if (hr == S_OK) { pContext->ObjectIDs = pObjectIDs; pContext->Properties = pProperties; pContext->Scope = Scope; hr = pContextMap->Add(pContext, strKey); CHECK_HR(hr, "Failed to insert bulk property operation context into our context Map"); } if (hr == S_OK) { *ppszBulkPropertiesContext = AtlAllocTaskWideString(strKey); if (*ppszBulkPropertiesContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate bulk properties context"); } } SAFE_RELEASE(pContext); return hr; }
HRESULT WpdObjectPropertiesBulk::CreateBulkPropertiesContext( _In_ ACCESS_SCOPE Scope, _In_ ContextMap* pContextMap, _In_ IPortableDeviceValuesCollection* pValuesCollection, _Outptr_result_nullonfailure_ LPWSTR* ppszBulkPropertiesContext) { HRESULT hr = S_OK; BulkPropertiesContext* pContext = NULL; CAtlStringW strKey; if((pContextMap == NULL) || (pValuesCollection == NULL) || (ppszBulkPropertiesContext == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } *ppszBulkPropertiesContext = NULL; pContext = new BulkPropertiesContext(); if(pContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate new bulk properties context"); } if (SUCCEEDED(hr)) { pContext->ValuesCollection = pValuesCollection; pContext->Scope = Scope; hr = pContextMap->Add(pContext, strKey); CHECK_HR(hr, "Failed to insert bulk property operation context into our context Map"); } if (SUCCEEDED(hr)) { *ppszBulkPropertiesContext = AtlAllocTaskWideString(strKey); if (*ppszBulkPropertiesContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate bulk properties context"); } } SAFE_RELEASE(pContext); 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 WpdObjectManagement::CreateObjectManagementContext( __inout ContextMap* pContextMap, __in LPCWSTR pszObjectName, __in IPortableDeviceValues* pObjectProperties, __in BOOL bUpdateRequest, __deref_out_opt LPWSTR* ppszObjectManagementContext) { HRESULT hr = S_OK; GUID guidContext = GUID_NULL; ObjectManagementContext* pContext = NULL; CComBSTR bstrContext; if((pContextMap == NULL) || (pObjectProperties == NULL) || (pszObjectName == NULL) || (ppszObjectManagementContext == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } *ppszObjectManagementContext = NULL; hr = CoCreateGuid(&guidContext); if (hr == S_OK) { bstrContext = guidContext; if(bstrContext.Length() == 0) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to create BSTR from GUID"); } } if (hr == S_OK) { pContext = new ObjectManagementContext(); if(pContext != NULL) { CAtlStringW strKey = bstrContext; pContext->Name = pszObjectName; pContext->ObjectProperties = pObjectProperties; pContext->UpdateRequest = bUpdateRequest; hr = pContextMap->Add(strKey, pContext); CHECK_HR(hr, "Failed to add object creation context to client context map"); pContext->Release(); } else { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate object creation context"); } } if (hr == S_OK) { *ppszObjectManagementContext = AtlAllocTaskWideString(bstrContext); } return hr; }
/** * This method is called when we receive a WPD_COMMAND_COMMON_GET_OBJECT_IDS_FROM_PERSISTENT_UNIQUE_IDS * command. * * The parameters sent to us are: * - WPD_PROPERTY_COMMON_PERSISTENT_UNIQUE_IDS: Contains an IPortableDevicePropVariantCollection of VT_LPWSTR, * indicating the PersistentUniqueIDs. * * The driver should: * - Iterate through the PersistentUniqueIDs, and convert to a currently valid object id. * This object ID list should be returned as an IPortableDevicePropVariantCollection of VT_LPWSTR * in WPD_PROPERTY_COMMON_OBJECT_IDS. * Order is implicit, i.e. the first element in the Persistent Unique ID list corresponds to the * to the first element of the ObjectID list and so on. * * For those elements where an existing ObjectID could not be found (e.g. the * object is no longer present on the device), the element will contain the * empty string (L""). */ HRESULT WpdBaseDriver::OnGetObjectIDsFromPersistentUniqueIDs( _In_ IPortableDeviceValues* pParams, _In_ IPortableDeviceValues* pResults) { HRESULT hr = S_OK; DWORD dwCount = 0; CComPtr<IPortableDevicePropVariantCollection> pPersistentIDs; CComPtr<IPortableDevicePropVariantCollection> pObjectIDs; if((pParams == NULL) || (pResults == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } // Get the list of Persistent IDs if (hr == S_OK) { hr = pParams->GetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_COMMON_PERSISTENT_UNIQUE_IDS, &pPersistentIDs); CHECK_HR(hr, "Failed to get WPD_PROPERTY_COMMON_PERSISTENT_UNIQUE_IDS"); } // Create the collection to hold the ObjectIDs if (hr == S_OK) { hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDevicePropVariantCollection, (VOID**) &pObjectIDs); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection"); } // Iterate through the persistent ID list and add the equivalent object ID for each element. if (hr == S_OK) { hr = pPersistentIDs->GetCount(&dwCount); CHECK_HR(hr, "Failed to get count from persistent ID collection"); if (hr == S_OK) { DWORD dwIndex = 0; PROPVARIANT pvPersistentID = {0}; PROPVARIANT pvObjectID = {0}; PropVariantInit(&pvPersistentID); PropVariantInit(&pvObjectID); for(dwIndex = 0; dwIndex < dwCount; dwIndex++) { pvObjectID.vt = VT_LPWSTR; hr = pPersistentIDs->GetAt(dwIndex, &pvPersistentID); CHECK_HR(hr, "Failed to get persistent ID at index %d", dwIndex); // Since our persistent unique identifier are identical to our object // identifiers, we just return it back to the caller. if (hr == S_OK) { pvObjectID.pwszVal = AtlAllocTaskWideString(pvPersistentID.pwszVal); } if (hr == S_OK) { hr = pObjectIDs->Add(&pvObjectID); CHECK_HR(hr, "Failed to add next Object ID"); } PropVariantClear(&pvPersistentID); PropVariantClear(&pvObjectID); if(FAILED(hr)) { break; } } } } if (hr == S_OK) { hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_COMMON_OBJECT_IDS, pObjectIDs); CHECK_HR(hr, "Failed to set WPD_PROPERTY_COMMON_OBJECT_IDS"); } return hr; }
HRESULT WpdServiceMethods::StartMethod( _In_ IPortableDeviceValues* pParams, _Outptr_result_nullonfailure_ LPWSTR* ppwszMethodContext) { HRESULT hr = S_OK; ContextMap* pContextMap = NULL; ServiceMethodContext* pContext = NULL; GUID Method = GUID_NULL; CAtlStringW strKey; CComPtr<IPortableDeviceValues> pMethodParams; if((pParams == NULL) || (ppwszMethodContext == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } *ppwszMethodContext = NULL; // Check if the method is supported hr = pParams->GetGuidValue(WPD_PROPERTY_SERVICE_METHOD, &Method); CHECK_HR(hr, "Failed to get WPD_PROPERTY_SERVICE_METHOD"); if (SUCCEEDED(hr) && !m_pContactsService->IsMethodSupported(Method)) { hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); CHECK_HR(hr, "Unknown method %ws received",CComBSTR(Method)); } if (SUCCEEDED(hr)) { // Get the context map which the driver stored in pParams for convenience hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap); CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP"); } if (SUCCEEDED(hr)) { pContext = new ServiceMethodContext(); if(pContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate new method context"); } } if (SUCCEEDED(hr)) { hr = pContextMap->Add(pContext, strKey); CHECK_HR(hr, "Failed to insert method context into our context Map"); } if (SUCCEEDED(hr)) { hr = pContext->Initialize(this, pParams, strKey); CHECK_HR(hr, "Failed to initialize the method context"); } if (SUCCEEDED(hr)) { *ppwszMethodContext = AtlAllocTaskWideString(strKey); if (*ppwszMethodContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate method context string"); } } SAFE_RELEASE(pContextMap); SAFE_RELEASE(pContext); return hr; }
HRESULT WpdObjectPropertiesBulk::CreateBulkPropertiesContext( __in ACCESS_SCOPE Scope, __inout ContextMap* pContextMap, __in REFGUID guidObjectFormat, __in LPCWSTR pszParentObjectID, __in DWORD dwDepth, __in IPortableDeviceKeyCollection* pProperties, __deref_out_opt LPWSTR* ppszBulkPropertiesContext) { HRESULT hr = S_OK; BulkPropertiesContext* pContext = NULL; CAtlStringW strKey; CComPtr<IPortableDevicePropVariantCollection> pObjectIDs; if((pContextMap == NULL) || (pszParentObjectID == NULL) || (ppszBulkPropertiesContext == NULL)) { hr = E_POINTER; CHECK_HR(hr, "Cannot have NULL parameter"); return hr; } *ppszBulkPropertiesContext = NULL; hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDevicePropVariantCollection, (VOID**) &pObjectIDs); CHECK_HR(hr, "Failed to CoCreate CLSID_IPortableDevicePropVariantCollection"); if (hr == S_OK) { hr = m_pDevice->GetObjectIDsByFormat(Scope, guidObjectFormat, pszParentObjectID, dwDepth, pObjectIDs); CHECK_HR(hr, "Faield to get list of object ids by format"); } if (hr == S_OK) { pContext = new BulkPropertiesContext(); if(pContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate new bulk properties context"); } } if (hr == S_OK) { pContext->Properties = pProperties; pContext->ObjectIDs = pObjectIDs; pContext->Scope = Scope; hr = pContextMap->Add(pContext, strKey); CHECK_HR(hr, "Failed to insert bulk property operation context into our context Map"); } if (hr == S_OK) { *ppszBulkPropertiesContext = AtlAllocTaskWideString(strKey); if (*ppszBulkPropertiesContext == NULL) { hr = E_OUTOFMEMORY; CHECK_HR(hr, "Failed to allocate bulk properties context"); } } SAFE_RELEASE(pContext); return hr; }
// Retreives the object identifier for the persistent unique identifer void GetObjectIdentifierFromPersistentUniqueIdentifier( IPortableDevice* pDevice) { if (pDevice == NULL) { printf("! A NULL IPortableDevice interface pointer was received\n"); return; } HRESULT hr = S_OK; WCHAR szSelection[81] = {0}; CComPtr<IPortableDeviceContent> pContent; CComPtr<IPortableDevicePropVariantCollection> pPersistentUniqueIDs; CComPtr<IPortableDevicePropVariantCollection> pObjectIDs; //<SnippetContentProp7> // Prompt user to enter an unique identifier to convert to an object idenifier. printf("Enter the Persistant Unique Identifier of the object you wish to convert into an object identifier.\n>"); hr = StringCbGetsW(szSelection,sizeof(szSelection)); if (FAILED(hr)) { printf("An invalid persistent object identifier was specified, aborting the query operation\n"); } //</SnippetContentProp7> // 1) Get an IPortableDeviceContent interface from the IPortableDevice interface to // access the content-specific methods. //<SnippetContentProp8> if (SUCCEEDED(hr)) { hr = pDevice->Content(&pContent); if (FAILED(hr)) { printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr); } } //</SnippetContentProp8> // 2) CoCreate an IPortableDevicePropVariantCollection interface to hold the the Unique Identifiers // to query for Object Identifiers. // // NOTE: This is a collection interface so more than 1 identifier can be requested at a time. // This sample only requests a single unique identifier. //<SnippetContentProp9> hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pPersistentUniqueIDs)); //</SnippetContentProp9> //<SnippetContentProp10> if (SUCCEEDED(hr)) { if (pPersistentUniqueIDs != NULL) { PROPVARIANT pv = {0}; PropVariantInit(&pv); // Initialize a PROPVARIANT structure with the object identifier string // that the user selected above. Notice we are allocating memory for the // PWSTR value. This memory will be freed when PropVariantClear() is // called below. pv.vt = VT_LPWSTR; pv.pwszVal = AtlAllocTaskWideString(szSelection); if (pv.pwszVal != NULL) { // Add the object identifier to the objects-to-delete list // (We are only deleting 1 in this example) hr = pPersistentUniqueIDs->Add(&pv); if (SUCCEEDED(hr)) { // 3) Attempt to get the unique idenifier for the object from the device hr = pContent->GetObjectIDsFromPersistentUniqueIDs(pPersistentUniqueIDs, &pObjectIDs); if (SUCCEEDED(hr)) { PROPVARIANT pvId = {0}; hr = pObjectIDs->GetAt(0, &pvId); if (SUCCEEDED(hr)) { printf("The persistent unique identifier '%ws' relates to object identifier '%ws' on the device.\n", szSelection, pvId.pwszVal); } else { printf("! Failed to get the object identifier for '%ws' from the IPortableDevicePropVariantCollection, hr = 0x%lx\n",szSelection, hr); } // Free the returned allocated string from the GetAt() call PropVariantClear(&pvId); } else { printf("! Failed to get the object identifier from persistent object idenifier '%ws', hr = 0x%lx\n",szSelection, hr); } } else { printf("! Failed to get the object identifier from persistent object idenifier because we could no add the persistent object identifier string to the IPortableDevicePropVariantCollection, hr = 0x%lx\n",hr); } } else { hr = E_OUTOFMEMORY; printf("! Failed to get the object identifier because we could no allocate memory for the persistent object identifier string, hr = 0x%lx\n",hr); } // Free any allocated values in the PROPVARIANT before exiting PropVariantClear(&pv); } } //</SnippetContentProp10> }
LPWSTR AFXAPI AfxTaskStringA2W(LPCSTR lpa) { LPWSTR lpw = AtlAllocTaskWideString(lpa); CoTaskMemFree((void*)lpa); return lpw; }
//</SnippetContentEnum1> // Recursively called function which enumerates using the specified // object identifier as the parent and populates the returned object // identifiers into an IPortableDevicePropVariantCollection object. void RecursiveEnumerateAndCopyToCollection( PCWSTR pszObjectID, IPortableDeviceContent* pContent, IPortableDevicePropVariantCollection* pObjectIDs) { HRESULT hr = S_OK; CComPtr<IEnumPortableDeviceObjectIDs> pEnumObjectIDs; // Add the object identifier being used as the parent during enumeration // to the collection. PROPVARIANT pv = {0}; PropVariantInit(&pv); // Allocated a new string in a PROPVARIANT so we can add it to our // collection object. pv.vt = VT_LPWSTR; pv.pwszVal = AtlAllocTaskWideString(pszObjectID); // Add the object identifer... hr = pObjectIDs->Add(&pv); // Free the allocated string in the PROPVARIANT PropVariantClear(&pv); // If we failed to add the object identifier, return immediately. if (FAILED(hr)) { printf("! Failed to add object identifier '%ws' to the IPortableDevicePropVariantCollection, hr = 0x%lx\n",pszObjectID, hr); return; } // Get an IEnumPortableDeviceObjectIDs interface by calling EnumObjects with the // specified parent object identifier. hr = pContent->EnumObjects(0, // Flags are unused pszObjectID, // Starting from the passed in object NULL, // Filter is unused &pEnumObjectIDs); if (FAILED(hr)) { printf("! Failed to get IEnumPortableDeviceObjectIDs from IPortableDeviceContent, hr = 0x%lx\n",hr); } // Loop calling Next() while S_OK is being returned. while(hr == S_OK) { DWORD cFetched = 0; PWSTR szObjectIDArray[NUM_OBJECTS_TO_REQUEST] = {0}; hr = pEnumObjectIDs->Next(NUM_OBJECTS_TO_REQUEST, // Number of objects to request on each NEXT call szObjectIDArray, // Array of PWSTR array which will be populated on each NEXT call &cFetched); // Number of objects written to the PWSTR array if (SUCCEEDED(hr)) { // Traverse the results of the Next() operation and recursively enumerate // Remember to free all returned object identifiers using CoTaskMemFree() for (DWORD dwIndex = 0; dwIndex < cFetched; dwIndex++) { RecursiveEnumerateAndCopyToCollection(szObjectIDArray[dwIndex], pContent, pObjectIDs); // Free allocated PWSTRs after the recursive enumeration call has completed. CoTaskMemFree(szObjectIDArray[dwIndex]); szObjectIDArray[dwIndex] = NULL; } } } }