Exemple #1
0
/**
 *\fn           HRESULT OutputString(const char *pszCaption, const char *pszText)
 *\brief        向输出窗体输出文字
 *\param[in]    const char * pszCaption 标题
 *\param[in]    const char * pszText 内容
 *\return       HRESULT 0成功,其它失败
 */
HRESULT CAddinProcess::OutputString(const char *pszCaption, const char *pszText)
{
    if (NULL == pszCaption || NULL == pszText) return E_INVALIDARG;

    CComPtr<Window> pWindow;
    HRESULT hr = m_pWindows->Item(CComVariant(EnvDTE::vsWindowKindOutput), &pWindow);

    if (NULL == pWindow) return E_INVALIDARG;

    CComPtr<IDispatch> pDisp;
    CComQIPtr<OutputWindow> pOutputWindow;
    hr = pWindow->get_Object(&pDisp);
    pOutputWindow = pDisp;

    if (NULL == pOutputWindow) return E_INVALIDARG;

    CComPtr<OutputWindowPanes> pOutputWindowPanes;
    hr = pOutputWindow->get_OutputWindowPanes(&pOutputWindowPanes);

    if (NULL == pOutputWindowPanes) return E_INVALIDARG;

    long nCount = 0;
    hr = pOutputWindowPanes->get_Count(&nCount);

    CComPtr<OutputWindowPane> pOutputWindowPane;

    int i = 1;
    for (; i <= nCount; i++)
    {
        VARIANT varIndex;
        VariantInit(&varIndex);
        varIndex.vt = VT_I4;
        varIndex.lVal = i;

        CComPtr<OutputWindowPane> pPane;
        hr = pOutputWindowPanes->Item(varIndex, &pPane);

        if (NULL == pPane) continue;

        BSTR bstrName;
        pPane->get_Name(&bstrName);

        std::string name = BstrToStr(bstrName);

        if (0 == strcmp(name.c_str(), pszCaption))
        {
            pOutputWindowPane = pPane;
            break;
        }
    }

    if (i > nCount)
    {
        hr = pOutputWindowPanes->Add(CComBSTR(pszCaption), &pOutputWindowPane);
    }

    hr = pOutputWindowPane->OutputString(CComBSTR(pszText));

    return hr;
}
Exemple #2
0
void TestPropSheetExt::MultipleSelection()
{
	CComPtr<MSF::CFileList> rfilelist = MSF::CFileList::CreateInstance();

	rfilelist->Add(MSF::GetModuleDirectory() + _T("sample1.vvv"));
	rfilelist->Add(MSF::GetModuleDirectory() + _T("sample2.vvv"));

	TestExecutePropSheetExt(rfilelist);
}
/**
 *  This method is called when we receive a WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_FORMATS
 *  command.  This message is sent when the client needs to know the possible formats supported
 *  by the specified content type (e.g. for image objects, the driver may choose to support JPEG and BMP files).
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_CAPABILITIES_CONTENT_TYPE - a GUID value containing the content type
 *    whose formats the caller is interested in.  If the value is WPD_CONTENT_TYPE_ALL, then the driver
 *    must return a list of all formats supported by the device.
 *
 *  The driver should:
 *  - Return an IPortableDevicePropVariantCollection (of type VT_CLSID) in
 *      WPD_PROPERTY_CAPABILITIES_FORMATS, indicating the formats supported by the
 *      specified content type.
 *      If there are no formats supported by the specified content type, the driver should return an
 *      empty collection.
 */
HRESULT WpdCapabilities::OnGetSupportedFormats(
    _In_ IPortableDeviceValues*  pParams,
    _In_ IPortableDeviceValues*  pResults)
{
    HRESULT hr              = S_OK;
    GUID    guidContentType = GUID_NULL;
    CComPtr<IPortableDevicePropVariantCollection> pFormats;

    // First get ALL parameters for this command.  If we cannot get ALL parameters
    // then E_INVALIDARG should be returned and no further processing should occur.

    // Get the content type whose supported formats have been requested
    if (hr == S_OK)
    {
        hr = pParams->GetGuidValue(WPD_PROPERTY_CAPABILITIES_CONTENT_TYPE, &guidContentType);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_CAPABILITIES_CONTENT_TYPE");
    }

    // CoCreate a collection to store the supported formats.
    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDevicePropVariantCollection,
                              (VOID**) &pFormats);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection");
    }

    // Add the supported formats for the specified content type to the collection.
    if (hr == S_OK)
    {
        PROPVARIANT pv = {0};
        PropVariantInit(&pv);
        // Don't call PropVariantClear, since we did not allocate the memory for these GUIDs

        if ((guidContentType   == WPD_CONTENT_TYPE_DOCUMENT) ||
            ((guidContentType  == WPD_CONTENT_TYPE_ALL)))
        {
            // Add WPD_OBJECT_FORMAT_TEXT to the supported formats collection
            pv.vt    = VT_CLSID;
            pv.puuid = (CLSID*)&WPD_OBJECT_FORMAT_TEXT;
            hr = pFormats->Add(&pv);
            CHECK_HR(hr, "Failed to add WPD_OBJECT_FORMAT_TEXT");
        }
    }

    // Set the WPD_PROPERTY_CAPABILITIES_FORMATS value in the results.
    if (hr == S_OK)
    {
        hr = pResults->SetIUnknownValue(WPD_PROPERTY_CAPABILITIES_FORMATS, pFormats);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_CAPABILITIES_FORMATS");
    }

    return hr;
}
Exemple #4
0
HRESULT
AsdkSheetSet::addResourceFileLocation(char* resourceFileLocation)
{
	if(FAILED(isInitialized("addResourceFileLocation")))
		return E_FAIL;
	
	 // lock the the database first before doing any operation on it
    if (FAILED(LockDatabase()))
	{
		acutPrintf("\n Database lock failed!");
        return E_FAIL;
	}

	CComPtr<IAcSmResources> pResources = NULL;

    if (FAILED(m_pSheetSet->GetResources(&pResources)))
        return E_FAIL;
    
   
	CComBSTR bstrResourceLoc(resourceFileLocation);

    CComPtr<IAcSmFileReference> pFileReference = NULL;
    if (FAILED(pFileReference.CoCreateInstance(L"AcSmComponents.AcSmFileReference")))
	{
        return E_POINTER;
	}

    if (FAILED(pFileReference->InitNew(m_pDb)))
	{
        return E_FAIL;
	}

    if (FAILED(pFileReference->SetFileName(bstrResourceLoc)))
	{
        return E_FAIL;
	}

    // add the resource location.
    if (FAILED(pResources->Add(pFileReference)))
        return E_FAIL;

	// Unlock database
	if (FAILED(UnlockDatabase())) 
	{
		acutPrintf("\n Cannot unlock database");
        return E_FAIL;
	}

	return S_OK;
}
/**
 *  This method is called when we receive a WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_FUNCTIONAL_CATEGORIES
 *  command.
 *
 *  The parameters sent to us are:
 *  - none.
 *
 *  The driver should:
 *  - Return an IPortableDevicePropVariantCollection (of type VT_CLSID) in
 *      WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORIES, containing
 *      the supported functional categories for this device.
 */
HRESULT WpdCapabilities::OnGetFunctionalCategories(
    _In_ IPortableDeviceValues*  pParams,
    _In_ IPortableDeviceValues*  pResults)
{
    HRESULT hr = S_OK;
    CComPtr<IPortableDevicePropVariantCollection> pFunctionalCategories;

    UNREFERENCED_PARAMETER(pParams);

    // CoCreate a collection to store the supported functional categories.
    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDevicePropVariantCollection,
                              (VOID**) &pFunctionalCategories);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection");
    }

    // Add the supported functional categories to the collection.
    if (hr == S_OK)
    {
        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 = (GUID*) &g_SupportedFunctionalCategories[dwIndex];

            hr = pFunctionalCategories->Add(&pv);
            CHECK_HR(hr, "Failed to add supported functional category at index %d", dwIndex);
            if (FAILED(hr))
            {
                break;
            }
        }
    }

    // Set the WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORIES value in the results.
    if (hr == S_OK)
    {
        hr = pResults->SetIUnknownValue(WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORIES, pFunctionalCategories);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORIES");
    }

    return hr;
}
Exemple #6
0
void ToolCollection::AddSelfToWindowsFirewall(const CAtlStringW name)
{
	CComPtr<INetFwMgr> FwMgr;
	CComPtr<INetFwPolicy> FwPolocy;
	CComPtr<INetFwProfile> FwProfile;

	if(FAILED(FwMgr.CoCreateInstance( __uuidof(NetFwMgr),nullptr,CLSCTX_INPROC_SERVER))) return;
	if(FAILED(FwMgr->get_LocalPolicy(&FwPolocy))) return;
	if(FAILED(FwPolocy->get_CurrentProfile(&FwProfile))) return;
	VARIANT_BOOL res;
	if(FAILED(FwProfile->get_FirewallEnabled(&res))) return;
	if(res==VARIANT_FALSE) return;

	if(FAILED(FwProfile->get_ExceptionsNotAllowed(&res))) return;
	if(res==VARIANT_TRUE) return;

	CComPtr<INetFwAuthorizedApplication> FwApp;
	CComPtr<INetFwAuthorizedApplications> FwApps;
	if(FAILED(FwProfile->get_AuthorizedApplications(&FwApps))) return;

	CAtlStringW filename,fullfilename;
	::GetModuleFileNameW(nullptr,filename.GetBuffer(MAX_PATH),MAX_PATH);
	filename.ReleaseBuffer();
	DWORD size=::GetFullPathName(filename,0,0,0);
	size=GetFullPathName(filename,size,fullfilename.GetBuffer(size),nullptr);
	fullfilename.ReleaseBuffer();

	if(SUCCEEDED(FwApps->Item(CComBSTR(fullfilename),&FwApp)))
	{
		FwApp->put_Enabled(VARIANT_TRUE);
	}
	else
	{
		if(FAILED(FwApp.CoCreateInstance(__uuidof(NetFwAuthorizedApplication),
			nullptr,CLSCTX_INPROC_SERVER))) return;

		if(FAILED(FwApp->put_Name(CComBSTR(name)))) return;

		if(FAILED(FwApp->put_ProcessImageFileName(CComBSTR(fullfilename)))) return;
		if(FAILED(FwApp->put_Enabled(VARIANT_TRUE)) ) return;

		FwApps->Add(FwApp);
	}
}
Exemple #7
0
HRESULT
AsdkSheetSet::addSheetSelectionSet(char* selSetName,			 // Name of selection set
					     		   char* selSetDesc,			 // Description 
							       IAcSmSheetSelSet **pSelSet) // Output pointer to selection set
{

	if(FAILED(isInitialized("addSheetSelectionSet")))
		return E_FAIL;
	
	 // lock the the database first before doing any operation on it
    if (FAILED(LockDatabase()))
	{
		acutPrintf("\n Database lock failed!");
        return E_FAIL;
	}

	CComPtr<IAcSmSheetSelSets> pSelSetS = NULL;
    if (FAILED(m_pSheetSet->GetSheetSelSets(&pSelSetS)) || (pSelSetS == NULL))
    {
		acutPrintf("\n addSheetSelectionSet failed! Cannot get selection sets!!");
        return E_FAIL;
    }
  

    // add a selection set to the selection set collection of the sheet set
    CComBSTR selSet(selSetName);
    CComBSTR selDesc(selSetDesc);

    if (FAILED (pSelSetS->Add(selSet, selDesc, pSelSet)))
    {
		acutPrintf("\n addSheetSelectionSet failed! Cannot add selection set %s!!", selSetName);
        return E_FAIL;
    }

	// Unlock database
	if (FAILED(UnlockDatabase())) 
	{
		acutPrintf("\n Cannot unlock database");
        return E_FAIL;
	}

    return S_OK;
}
/**
 *  This method is called when we receive a WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_COMMANDS
 *  command.
 *
 *  The parameters sent to us are:
 *  - none.
 *
 *  The driver should:
 *  - Return all commands supported by this driver as an
 *    IPortableDeviceKeyCollection in WPD_PROPERTY_CAPABILITIES_SUPPORTED_COMMANDS.
 *    This includes custom commands, if any.
 *
 *    Note that certain commands require a "command target" to function correctly.
 *    (e.g. delete object command) It is understood that not all objects are necessarily
 *    valid targets (e.g. you cannot delete the device object).
 */
HRESULT WpdCapabilities::OnGetSupportedCommands(
    _In_ IPortableDeviceValues*  pParams,
    _In_ IPortableDeviceValues*  pResults)
{
    HRESULT hr = S_OK;
    CComPtr<IPortableDeviceKeyCollection> pCommands;
    UNREFERENCED_PARAMETER(pParams);

    // CoCreate a collection to store the supported commands.
    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDeviceKeyCollection,
                              (VOID**) &pCommands);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceKeyCollection");
    }

    // Add the supported commands to the collection.
    if (hr == S_OK)
    {
        for (DWORD dwIndex = 0; dwIndex < ARRAYSIZE(g_SupportedCommands); dwIndex++)
        {
            hr = pCommands->Add(g_SupportedCommands[dwIndex]);
            CHECK_HR(hr, "Failed to add supported command at index %d", dwIndex);
            if (FAILED(hr))
            {
                break;
            }
        }
    }

    // Set the WPD_PROPERTY_CAPABILITIES_SUPPORTED_COMMANDS value in the results.
    if (hr == S_OK)
    {
        hr = pResults->SetIUnknownValue(WPD_PROPERTY_CAPABILITIES_SUPPORTED_COMMANDS, pCommands);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_CAPABILITIES_SUPPORTED_COMMANDS");
    }

    return hr;
}
STDMETHODIMP CTangramHelper::get_OutputPane(IDispatch** pVal)
{
    CComBSTR bstrDTE(L"DTE");
    CComPtr<IDispatch> pDisp;
    if (theApp.m_pTangramCore)
    {
        theApp.m_pTangramCore->get_TangramExtender(bstrDTE,&pDisp);
        if (pDisp)
        {
            //pDisp.p->Release();
            CComQIPtr<DTE2> pDTE2(pDisp);
            CComPtr<Window> pWnd;
            pDTE2->get_MainWindow(&pWnd);
            long h = 0;
            if(pWnd)
                pWnd->get_HWnd(&h);
            CComPtr<ToolWindows> pToolWindows;
            pDTE2->get_ToolWindows(&pToolWindows);
            if (pToolWindows)
            {
                CComPtr<VxDTE::OutputWindow> pOutWnd;
                pToolWindows->get_OutputWindow(&pOutWnd);
                if (pOutWnd)
                {
                    CComPtr<OutputWindowPane> pPane;
                    CComPtr<OutputWindowPanes> pPanes;
                    pOutWnd->get_OutputWindowPanes(&pPanes);
                    pPanes->Add(CComBSTR(L"Tangram"), &pPane);
                    pPane->OutputString(CComBSTR(L"Welcome to Tangram!\r\n"));
                    *pVal = pPane.p;
                    (*pVal)->AddRef();
                    m_pOutputWindowPane = pPane.Detach();
                    //m_pOutputWindowPane->AddRef();
                }
            }
        }
    }

    return S_OK;
}
Exemple #10
0
// Post a data updated event
HRESULT CSampleEvents::PostDataEvent(IPortableDeviceValues* pValues)
{
    HRESULT hr = (NULL == m_spSensorCXT) ? E_UNEXPECTED : S_OK ;

    if (SUCCEEDED(hr))
    {
        CComPtr<IPortableDeviceValuesCollection> spValuesCollection;
        hr = spValuesCollection.CoCreateInstance(CLSID_PortableDeviceValuesCollection);

        if (SUCCEEDED(hr))
        {
            hr = spValuesCollection->Add(pValues);

            if (SUCCEEDED(hr))
            {
                hr = m_spSensorCXT->PostEvent(g_wszSensorID, spValuesCollection);
            }
        }
    }

    return hr;
}
Exemple #11
0
STDMETHODIMP CSWFBuilder::Process(
	/*[in]*/ BSTR /*sFile*/,
	/*[in]*/ ISXMLElement* pXML)
{
	if ( ! pXML )
		return E_POINTER;

	CComPtr <ISXMLElements> pISXMLRootElements;
	HRESULT hr = pXML->get_Elements( &pISXMLRootElements );
	if ( FAILED(hr) ) return hr;

	CComPtr <ISXMLElement> pXMLRootElement;
	hr = pISXMLRootElements->Create( CComBSTR("videos"), &pXMLRootElement );
	if ( FAILED(hr) ) return hr;

	CComPtr <ISXMLAttributes> pISXMLRootAttributes;
	hr = pXMLRootElement->get_Attributes( &pISXMLRootAttributes );
	if ( FAILED(hr) ) return hr;

	pISXMLRootAttributes->Add( CComBSTR("xmlns:xsi"),
		CComBSTR("http://www.w3.org/2001/XMLSchema-instance") );
	pISXMLRootAttributes->Add( CComBSTR("xsi:noNamespaceSchemaLocation"),
		CComBSTR("http://schemas.getenvy.com/Video.xsd") );

	CComPtr <ISXMLElements> pISXMLElements;
	hr = pXMLRootElement->get_Elements( &pISXMLElements );
	if ( FAILED(hr) ) return hr;

	CComPtr <ISXMLElement> pXMLElement;
	hr = pISXMLElements->Create( CComBSTR("video"), &pXMLElement );
	if ( FAILED(hr) ) return hr;

	CComPtr <ISXMLAttributes> pISXMLAttributes;
	hr = pXMLElement->get_Attributes( &pISXMLAttributes );
	if ( FAILED(hr) ) return hr;

	pISXMLAttributes->Add( CComBSTR("type"), CComBSTR("Shockwave Flash") );
	pISXMLAttributes->Add( CComBSTR("codec"), CComBSTR("SWF") );
	CString tmp;
	tmp.Format( L"%lu", cx );
	pISXMLAttributes->Add( CComBSTR("width"), CComBSTR(tmp) );
	tmp.Format( L"%lu", cy );
	pISXMLAttributes->Add( CComBSTR("height"), CComBSTR(tmp) );

	return hr;
}
/**
 *  This method is called when we receive a WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_NEXT
 *  command.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT: the context the driver returned to
 *      the client in OnGetValuesByObjectListStart.
 *
 *  The driver should:
 *  - Write the next set of property values, and return the write results in WPD_PROPERTY_OBJECT_PROPERTIES_BULK_WRITE_RESULTS.
 *    If there are no more properties to be written, an empty collection should be returned.
 *  - It is up to the driver to write as many object property values as it wants.  If zero write results are returned
 *    it is assumed the bulk operation is complete and the WPD_COMMAND_OBJECT_PROPERTIES_BULK_SET_VALUES_BY_OBJECT_LIST_END
 *    will be called next.
 *
 *  - S_OK should be returned if the collection can be returned successfully.
 *  - Any error return indicates that the driver did not fill in any results, and the caller will
 *      not attempt to unpack any property values.
 */
HRESULT WpdObjectPropertiesBulk::OnSetValuesByObjectListNext(
    _In_    IPortableDeviceValues*  pParams,
    _In_    IPortableDeviceValues*  pResults)
{
    HRESULT                                  hr          = S_OK;
    LPWSTR                                   pwszContext = NULL;
    BulkPropertiesContext*                   pContext    = NULL;
    DWORD                                    cObjects    = 0;
    CComPtr<IPortableDeviceValues>           pEventParams;
    CComPtr<IPortableDeviceValuesCollection> pWriteResults;
    CComPtr<IPortableDeviceValuesCollection> pValuesCollection;

    hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT, &pwszContext);
    CHECK_HR(hr, "Failed to get WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT from IPortableDeviceValues");

    // Get the bulk property operation context
    if (SUCCEEDED(hr))
    {
        hr = GetClientContext(pParams, pwszContext, (IUnknown**) &pContext);
        CHECK_HR(hr, "Failed to get bulk property context");
    }

    // Make sure the the collection holds a ValuesCollection, then get the number of elements.
    if (SUCCEEDED(hr))
    {
        if(pContext->ValuesCollection != NULL)
        {
            hr = pContext->ValuesCollection->GetCount(&cObjects);
            CHECK_HR(hr, "Failed to get number of objectIDs from bulk properties context");
        }
        else
        {
            hr = E_INVALIDARG;
            CHECK_HR(hr, "Incorrect context specified - this context does not contain a values collection");
        }
    }

    // Create the collection to hold the write results
    if (SUCCEEDED(hr))
    {
        hr = CoCreateInstance(CLSID_PortableDeviceValuesCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDeviceValuesCollection,
                              (VOID**) &pWriteResults);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValuesCollection");
    }

    // Create the collection to hold the event parameters
    if (SUCCEEDED(hr))
    {
        hr = CoCreateInstance(CLSID_PortableDeviceValues,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDeviceValues,
                              (VOID**) &pEventParams);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues");
    }

    if (SUCCEEDED(hr))
    {
        for (DWORD dwIndex = pContext->NextObject; dwIndex < cObjects; dwIndex++)
        {
            CComPtr<IPortableDeviceValues> pValues;
            CComPtr<IPortableDeviceValues> pSetResults;

            bool bObjectChanged = false;

            hr = pContext->ValuesCollection->GetAt(dwIndex, &pValues);
            CHECK_HR(hr, "Failed to get next values from bulk properties context");

            // CoCreate a collection to store the per object results.
            if (SUCCEEDED(hr))
            {
                hr = CoCreateInstance(CLSID_PortableDeviceValues,
                                      NULL,
                                      CLSCTX_INPROC_SERVER,
                                      IID_IPortableDeviceValues,
                                      (VOID**) &pSetResults);
                CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues");
            }

            if (SUCCEEDED(hr))
            {
                LPWSTR pszObjectID = NULL;

                // Get which object this is for
                hr =  pValues->GetStringValue(WPD_OBJECT_ID, &pszObjectID);
                if (SUCCEEDED(hr))
                {
                    hr = m_pDevice->SetPropertyValues(pContext->Scope, pszObjectID, pValues, pSetResults, pEventParams, &bObjectChanged);
                    CHECK_HR(hr, "Failed to get count of values");
                }

                if (SUCCEEDED(hr))
                {
                    // Ensure the write results contain which ObjectID this was for
                    hr = pSetResults->SetStringValue(WPD_OBJECT_ID, pszObjectID);
                    CHECK_HR(hr, "Failed to set WPD_OBJECT_ID in write results");

                    if (SUCCEEDED(hr) && bObjectChanged)
                    {
                        // set property values is successful and object has changed, so we post an event.  
                        // This is best effort, so errors are ignored
                        HRESULT hrEvent = PostWpdEvent(pParams, pEventParams);  
                        CHECK_HR(hrEvent, "Failed post event for updated object [%ws] (errors ignored)", pszObjectID);
                    }
                    pEventParams->Clear();
                }

                CoTaskMemFree(pszObjectID);
            }

            if (SUCCEEDED(hr))
            {
                hr = pWriteResults->Add(pSetResults);
                CHECK_HR(hr, "Failed to add IPortableDeviceValues to IPortableDeviceValuesCollection");
            }

            pContext->NextObject++;
        }
    }

    if (SUCCEEDED(hr))
    {
        hr = pResults->SetIUnknownValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_WRITE_RESULTS, pWriteResults);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_PROPERTIES_BULK_WRITE_RESULTS");
    }

    // Free the memory.  CoTaskMemFree ignores NULLs so no need to check.
    CoTaskMemFree(pwszContext);

    SAFE_RELEASE(pContext);

    return hr;
}
Exemple #13
0
HRESULT
AsdkSheetSet::addCalloutBlock(char* blockName,
							  char* drawingName)
{
	if(FAILED(isInitialized("addCalloutBlock")))
		return E_FAIL;

	// lock the the database first before doing any operation on it
    if (FAILED(LockDatabase()))
	{
		acutPrintf("\n Database lock failed!");
        return E_FAIL;
	}

	CComPtr<IAcSmCalloutBlocks> pCalloutBlk = NULL;
	if (FAILED(m_pSheetSet->GetCalloutBlocks(&pCalloutBlk)))
	{
		acutPrintf("\n addCalloutBlock failed! Cannot get callout blocks!!");
		return E_FAIL;
	}

	CComBSTR bstrBlockName(blockName);
	CComBSTR bstrFileName(drawingName);

	CComPtr<IAcSmAcDbBlockRecordReference> pCalloutRef = NULL;
	if (FAILED(pCalloutRef.CoCreateInstance(L"AcSmComponents.AcSmAcDbBlockRecordReference")))
	{
		acutPrintf("\n addCalloutBlock failed! Cannot get named object reference!!");
		return E_POINTER;
	}
		

	if (FAILED(pCalloutRef->InitNew(m_pDb)))
		return E_FAIL;

	if (FAILED(pCalloutRef->SetFileName(bstrFileName)))
	{
		acutPrintf("\n addCalloutBlock failed! Cannot set file name %s!!", drawingName);
		return E_FAIL;
	}

	if (FAILED(pCalloutRef->SetName(bstrBlockName)))
	{
		acutPrintf("\n addCalloutBlock failed! Cannot set block name %s!!", blockName);
		return E_FAIL;
	}
	 
	if(FAILED(pCalloutBlk->Add(pCalloutRef)))
	{
		acutPrintf("\n addCalloutBlock failed! Cannot add callout reference!!");
		return E_FAIL;
	}

		// Unlock database
	if (FAILED(UnlockDatabase())) 
	{
		acutPrintf("\n Cannot unlock database");
        return E_FAIL;
	}

	return S_OK;
}
// 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>
}
/**
 *  This method is called when we receive a WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_NEXT
 *  command.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT: the context the driver returned to
 *      the client in OnGetValuesByObjectFormatStart.
 *
 *  The driver should:
 *  - Return the next set of property values in WPD_PROPERTY_OBJECT_PROPERTIES_BULK_VALUES.
 *    If there are no more properties to be read an
 *    empty collection should be returned.
 *  - It is up to the driver to return as many object property values as it wants.  If zero values are returned
 *    it is assumed the bulk operation is complete and the WPD_COMMAND_OBJECT_PROPERTIES_BULK_GET_VALUES_BY_OBJECT_FORMAT_END
 *    will be called next.
 *
 *  - S_OK should be returned if the collection can be returned successfully.
 *  - Any error return indicates that the driver did not fill in any results, and the caller will
 *      not attempt to unpack any property values.
 */
HRESULT WpdObjectPropertiesBulk::OnGetValuesByObjectFormatNext(
    _In_    IPortableDeviceValues*  pParams,
    _In_    IPortableDeviceValues*  pResults)
{
    HRESULT                                  hr = S_OK;
    LPWSTR                                   pwszContext = NULL;
    BulkPropertiesContext*                   pContext    = NULL;
    DWORD                                    cObjects    = 0;
    CComPtr<IPortableDeviceValuesCollection> pCollection;

    hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT, &pwszContext);
    CHECK_HR(hr, "Failed to get WPD_PROPERTY_OBJECT_PROPERTIES_BULK_CONTEXT from IPortableDeviceValues");

    // Get the bulk property operation context
    if (SUCCEEDED(hr))
    {
        hr = GetClientContext(pParams, pwszContext, (IUnknown**) &pContext);
        CHECK_HR(hr, "Failed to get bulk property context");
    }

    // Make sure the the collection holds VT_LPWSTR values.
    if (SUCCEEDED(hr))
    {
        hr = pContext->ObjectIDs->ChangeType(VT_LPWSTR);
        CHECK_HR(hr, "Failed to change objectIDs collection to VT_LPWSTR");
    }

    if (SUCCEEDED(hr))
    {
        hr = pContext->ObjectIDs->GetCount(&cObjects);
        CHECK_HR(hr, "Failed to get number of objectIDs from bulk properties context");
    }

    if (SUCCEEDED(hr))
    {
        cObjects = cObjects - pContext->NextObject;
        if(cObjects > MAX_OBJECTS_TO_RETURN)
        {
            cObjects = MAX_OBJECTS_TO_RETURN;
        }
    }

    if (SUCCEEDED(hr))
    {
        hr = CoCreateInstance(CLSID_PortableDeviceValuesCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDeviceValuesCollection,
                              (VOID**) &pCollection);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValuesCollection");
    }

    if (SUCCEEDED(hr))
    {
        for (DWORD dwIndex = pContext->NextObject, dwCount = 0; dwCount < cObjects; dwCount++, dwIndex++)
        {
            CComPtr<IPortableDeviceValues> pValues;
            PROPVARIANT pv = {0};
            PropVariantInit(&pv);
            hr = pContext->ObjectIDs->GetAt(dwIndex, &pv);
            CHECK_HR(hr, "Failed to get next object ID from bulk properties context");

            if (SUCCEEDED(hr))
            {
                hr = CoCreateInstance(CLSID_PortableDeviceValues,
                                      NULL,
                                      CLSCTX_INPROC_SERVER,
                                      IID_IPortableDeviceValues,
                                      (VOID**) &pValues);
                CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValuesCollection");
            }

            if (SUCCEEDED(hr))
            {
                // If a key list was supplied, get the specified object properties, other get all
                // properties.
                if(pContext->Properties != NULL)
                {
                    hr = m_pDevice->GetPropertyValues(pContext->Scope, pv.pwszVal, pContext->Properties, pValues);
                    CHECK_HR(hr, "Failed to get property values for [%ws]", pv.pwszVal);
                }
                else
                {
                    hr = m_pDevice->GetAllPropertyValues(pContext->Scope,pv.pwszVal, pValues);
                    CHECK_HR(hr, "Failed to get property values for [%ws]", pv.pwszVal);
                }
            }

            // Add the ObjectID to the returned results
            if (SUCCEEDED(hr))
            {
                hr = pValues->SetStringValue(WPD_OBJECT_ID, pv.pwszVal);
                CHECK_HR(hr, "Failed to set WPD_OBJECT_ID for %ws", pv.pwszVal);
            }

            if (SUCCEEDED(hr))
            {
                hr = pCollection->Add(pValues);
                CHECK_HR(hr, "Failed to add IPortableDeviceValues to IPortableDeviceValuesCollection");
            }

            PropVariantClear(&pv);
            pContext->NextObject++;
        }
    }

    if (SUCCEEDED(hr))
    {
        hr = pResults->SetIUnknownValue(WPD_PROPERTY_OBJECT_PROPERTIES_BULK_VALUES, pCollection);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_PROPERTIES_BULK_VALUES");
    }

    // Free the memory.  CoTaskMemFree ignores NULLs so no need to check.
    CoTaskMemFree(pwszContext);
    SAFE_RELEASE(pContext);

    return hr;
}
// Reads a set of properties for all objects.
void ReadContentPropertiesBulk(
    IPortableDevice*    pDevice)
{
    if (pDevice == NULL)
    {
        printf("! A NULL IPortableDevice interface pointer was received\n");
        return;
    }

    HRESULT                                       hr                = S_OK;
    GUID                                          guidContext       = GUID_NULL;
    CGetBulkValuesCallback*                       pCallback         = NULL;
    CComPtr<IPortableDeviceProperties>            pProperties;
    CComPtr<IPortableDevicePropertiesBulk>        pPropertiesBulk;
    CComPtr<IPortableDeviceValues>                pObjectProperties;
    CComPtr<IPortableDeviceContent>               pContent;
    CComPtr<IPortableDeviceKeyCollection>         pPropertiesToRead;
    CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;


    // 1) Get an IPortableDeviceContent interface from the IPortableDevice interface to
    // access the content-specific methods.
    hr = pDevice->Content(&pContent);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
    }

    // 2) Get an IPortableDeviceProperties interface from the IPortableDeviceContent interface
    // to access the property-specific methods.
    if (SUCCEEDED(hr))
    {
        hr = pContent->Properties(&pProperties);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }

    // 3) Check to see if the driver supports BULK property operations by call QueryInterface
    // on the IPortableDeviceProperties interface for IPortableDevicePropertiesBulk
    if (SUCCEEDED(hr))
    {
        hr = pProperties->QueryInterface(IID_PPV_ARGS(&pPropertiesBulk));
        if (FAILED(hr))
        {
            printf("This driver does not support BULK property operations.\n");
        }
    }

    // 4) CoCreate an IPortableDeviceKeyCollection interface to hold the the property keys
    // we wish to read.
    if (SUCCEEDED(hr))
    {
        hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_PPV_ARGS(&pPropertiesToRead));
        if (FAILED(hr))
        {
            printf("! Failed to CoCreate IPortableDeviceKeyCollection to hold the property keys to read, hr = 0x%lx\n",hr);
        }
    }                              

    if (SUCCEEDED(hr))
    {
        // 5) Populate the IPortableDeviceKeyCollection with the keys we wish to read.
        // NOTE: We are not handling any special error cases here so we can proceed with
        // adding as many of the target properties as we can.
        if (pPropertiesToRead != NULL)
        {
            HRESULT hrTemp = S_OK;
            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_PARENT_ID);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_PARENT_ID to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_NAME);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_NAME to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_PERSISTENT_UNIQUE_ID);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_PERSISTENT_UNIQUE_ID to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_FORMAT);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_FORMAT to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_CONTENT_TYPE);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_CONTENT_TYPE to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }
        }
    }

    // 6) Create an instance of the IPortableDevicePropertiesBulkCallback object.
    if (SUCCEEDED(hr))
    {
        pCallback = new (std::nothrow) CGetBulkValuesCallback();
        if (pCallback == NULL)
        {
            hr = E_OUTOFMEMORY;
            printf("! Failed to allocate CGetBulkValuesCallback, hr = 0x%lx\n", hr);
        }
    }

    // 7) Call our helper function CreateIPortableDevicePropVariantCollectionWithAllObjectIDs
    // to enumerate and create an IPortableDevicePropVariantCollection with the object
    // identifiers needed to perform the bulk operation on.
    if (SUCCEEDED(hr))
    {
        hr = CreateIPortableDevicePropVariantCollectionWithAllObjectIDs(pContent,
                                                                        &pObjectIDs);
    }


    // 8) Call QueueGetValuesByObjectList to initialize the Asynchronous
    // property operation.
    if (SUCCEEDED(hr))
    {
        hr = pPropertiesBulk->QueueGetValuesByObjectList(pObjectIDs,
                                                         pPropertiesToRead,
                                                         pCallback,
                                                         &guidContext);
        // 9) Call Start() to actually being the property operation
        if(SUCCEEDED(hr))
        {
            // Cleanup any previously created global event handles.
            if (g_hBulkPropertyOperationEvent != NULL)
            {
                CloseHandle(g_hBulkPropertyOperationEvent);
                g_hBulkPropertyOperationEvent = NULL;
            }

            // In order to create a simpler to follow example we create and wait infinitly
            // for the bulk property operation to complete and ignore any errors.
            // Production code should be written in a more robust manner.
            // Create the global event handle to wait on for the bulk operation
            // to complete.
            g_hBulkPropertyOperationEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
            if (g_hBulkPropertyOperationEvent != NULL)
            {
                // Call Start() to actually being the Asynchronous bulk operation.
                hr = pPropertiesBulk->Start(guidContext);
                if(FAILED(hr))
                {
                    printf("! Failed to start property operation, hr = 0x%lx\n", hr);
                }
            }
            else
            {
                printf("! Failed to create the global event handle to wait on for the bulk operation. Aborting operation.\n");
            }
        }
        else
        {
            printf("! QueueGetValuesByObjectList Failed, hr = 0x%lx\n", hr);
        }
    }

    // In order to create a simpler to follow example we will wait infinitly for the operation
    // to complete and ignore any errors.  Production code should be written in a more
    // robust manner.
    if (SUCCEEDED(hr))
    {
        if (g_hBulkPropertyOperationEvent != NULL)
        {
            WaitForSingleObject(g_hBulkPropertyOperationEvent, INFINITE);
        }
    }

    if (pCallback != NULL)
    {
        pCallback->Release();
        pCallback = NULL;
    }

    // Cleanup any created global event handles before exiting..
    if (g_hBulkPropertyOperationEvent != NULL)
    {
        CloseHandle(g_hBulkPropertyOperationEvent);
        g_hBulkPropertyOperationEvent = NULL;
    }
}
Exemple #17
0
HRESULT CConnect::OnConnection(LPDISPATCH Application, ext_ConnectMode ConnectMode, LPDISPATCH AddInInst, SAFEARRAY **custom)
{
	TSAUTO();
	Application->QueryInterface(__uuidof(IDispatch), reinterpret_cast<LPVOID*>(&this->m_spApplication));
	AddInInst->QueryInterface(__uuidof(IDispatch), reinterpret_cast<LPVOID*>(&this->m_spAddInInstance));
	//是否显示按钮
	CRegKey key;
	DWORD dwValue;
	if(key.Open(HKEY_CURRENT_USER, _T("Software\\WordEncLock")) == ERROR_SUCCESS){
		if (key.QueryValue(dwValue, _T("silent")) == ERROR_SUCCESS){
			if (dwValue == 1){
				g_sIsSilent = TRUE;
			}
		}
	}
	key.Close();
	if (g_sIsSilent){
		return S_OK;
	}
	CComQIPtr<_Application> spApp(Application);
	ATLASSERT(spApp);
	if (!spApp){//获取失败说明是excel
		//g_sIsSilent = TRUE;
		return S_OK;
	}
	g_Application = spApp;
	
	HRESULT hr;
	CComPtr<Office::_CommandBars>  spCmdBars; 
	hr =  g_Application->get_CommandBars(&spCmdBars);
	if(FAILED(hr))
		return hr;
	ATLASSERT(spCmdBars);

	// now we add a new toolband to Word
	// to which we''ll add 2 buttons
	CComVariant vName("");
	CComPtr<Office::CommandBar> spNewCmdBar;

	CComVariant vPos(1); 
	CComVariant vTemp(VARIANT_TRUE); // menu is temporary        
	CComVariant vEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);            
	spNewCmdBar = spCmdBars->Add(vName, vPos, vEmpty, vTemp);

	CComPtr < Office::CommandBarControls> spBarControls;
	spBarControls = spNewCmdBar->GetControls();
	ATLASSERT(spBarControls);


	CComVariant vToolBarType(1);
	CComVariant vShow(VARIANT_TRUE);
	CComPtr<Office::CommandBarControl>  spNewBar; 

	// add first button
	spNewBar = spBarControls->Add(vToolBarType,vEmpty,vEmpty,vEmpty,vShow); 
	ATLASSERT(spNewBar);

	CComQIPtr < Office::_CommandBarButton> spCmdButton(spNewBar);

	ATLASSERT(spCmdButton);
	m_spButton = spCmdButton;
	AppEvents::DispEventAdvise(m_spButton);

	HBITMAP hBmp =(HBITMAP)::LoadImage(g_hModule,
		MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP,0,0,LR_LOADMAP3DCOLORS);
	::OpenClipboard(NULL);
	::EmptyClipboard();
	::SetClipboardData(CF_BITMAP, (HANDLE)hBmp);
	::CloseClipboard();
	::DeleteObject(hBmp);        

	spCmdButton->PutStyle(Office::msoButtonIconAndWrapCaption);
	hr = spCmdButton->PasteFace();
	if (FAILED(hr))
		return hr;
	spCmdButton->PutVisible(VARIANT_TRUE); 
	spCmdButton->PutCaption(OLESTR("Word安全锁")); 
	spCmdButton->PutEnabled(VARIANT_TRUE);
	spCmdButton->PutTooltipText(OLESTR("Word安全锁")); 
	spCmdButton->PutTag(OLESTR("给Word文档加密")); 
	spNewCmdBar->PutVisible(VARIANT_TRUE); 
	return S_OK;
}
Exemple #18
0
HRESULT CDevice::GetDeviceFriendlyName(
    __deref_out_opt LPWSTR*   pwszDeviceFriendlyName)
{
    HRESULT hr = S_OK;

    CComPtr<IPortableDeviceValues>        pParams;
    CComPtr<IPortableDeviceValues>        pResults;
    CComPtr<IPortableDeviceKeyCollection> pKeys;
    CComPtr<IPortableDeviceValues>        pValues;

    if (pwszDeviceFriendlyName == NULL)
    {
        hr = E_INVALIDARG;
        return hr;
    }

    *pwszDeviceFriendlyName = NULL;

    // CoCreate a collection to store the WPD_COMMAND_OBJECT_PROPERTIES_GET command parameters.
    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDeviceValues,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDeviceValues,
                              (VOID**)&pParams);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues");
    }

    // CoCreate a collection to store the WPD_COMMAND_OBJECT_PROPERTIES_GET command results.
    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDeviceValues,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDeviceValues,
                              (VOID**)&pResults);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues");
    }

    // CoCreate a collection to store the requested property keys.  In our case, we are requesting just the device friendly name
    // (WPD_DEVICE_FRIENDLY_NAME)
    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDeviceKeyCollection,
                              (VOID**)&pKeys);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceKeyCollection for results");
    }

    // Set the params
    if (hr == S_OK)
    {
        hr = pParams->SetGuidValue(WPD_PROPERTY_COMMON_COMMAND_CATEGORY, WPD_COMMAND_OBJECT_PROPERTIES_GET.fmtid);
        CHECK_HR(hr, ("Failed to set WPD_PROPERTY_COMMON_COMMAND_CATEGORY"));
    }

    if (hr == S_OK)
    {
        hr = pParams->SetUnsignedIntegerValue(WPD_PROPERTY_COMMON_COMMAND_ID, WPD_COMMAND_OBJECT_PROPERTIES_GET.pid);
        CHECK_HR(hr, ("Failed to set WPD_PROPERTY_COMMON_COMMAND_ID"));
    }

    if (hr == S_OK)
    {
        hr = pParams->SetStringValue(WPD_PROPERTY_OBJECT_PROPERTIES_OBJECT_ID, WPD_DEVICE_OBJECT_ID);
        CHECK_HR(hr, ("Failed to set WPD_PROPERTY_OBJECT_PROPERTIES_OBJECT_ID"));
    }

    if (hr == S_OK)
    {
        hr = pKeys->Add(WPD_DEVICE_FRIENDLY_NAME);
        CHECK_HR(hr, ("Failed to add WPD_DEVICE_FRIENDLY_NAME to key collection"));
    }

    if (hr == S_OK)
    {
        hr = pParams->SetIPortableDeviceKeyCollectionValue(WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_KEYS, pKeys);
        CHECK_HR(hr, ("Failed to set WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_KEYS"));
    }

    // Make the call
    if (hr == S_OK)
    {
        hr = m_pWpdBaseDriver->DispatchWpdMessage(pParams, pResults);
        CHECK_HR(hr, ("Failed to dispatch message to get supported content types"));
    }

    // Get the results
    if (hr == S_OK)
    {
        hr = pResults->GetIPortableDeviceValuesValue(WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_VALUES, &pValues);
        CHECK_HR(hr, ("Failed to get WPD_PROPERTY_OBJECT_PROPERTIES_PROPERTY_VALUES"));
    }

    if (hr == S_OK)
    {
        hr = pValues->GetStringValue(WPD_DEVICE_FRIENDLY_NAME, pwszDeviceFriendlyName);
        CHECK_HR(hr, ("Failed to get WPD_DEVICE_FRIENDLY_NAME"));
    }

    return hr;
}
/**
 *  This method is called when we receive a WPD_COMMAND_OBJECT_MANAGEMENT_MOVE_OBJECTS
 *  command.
 *
 * This command will move the specified objects to the destination folder.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS : the ObjectIDs, indicating which objects to move.  These may
 *      be folder objects.
 *  - WPD_PROPERTY_OBJECT_MANAGEMENT_DESTINATION_FOLDER_OBJECT_ID: Indicates the destination folder for the move operation.
 *
 *  The driver should:
 *  - Attempt to Move the object specified in WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS to the folder specified in
 *    WPD_PROPERTY_OBJECT_MANAGEMENT_DESTINATION_FOLDER_OBJECT_ID.
 * - Fill out the operation results in WPD_PROPERTY_OBJECT_MANAGEMENT_MOVE_RESULTS.  It contains an IportableDevicePropVariantCollection of
 *   VT_ERROR values indicating the success or failure of the operation for that element.
 *   Order is implicit, i.e. the first element of WPD_PROPERTY_OBJECT_MANAGEMENT_MOVE_RESULTS corresponds to the first element of WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS and so on.
 *  - The driver should return:
 *      - S_OK if all objects were moved successfully.
 *      - S_FALSE if any object move failed.
 *      - An error return indicates that the driver did not move any objects, and
 *        WPD_PROPERTY_OBJECT_MANAGEMENT_MOVE_RESULTS is ignored.
 */
HRESULT WpdObjectManagement::OnMove(
    IPortableDeviceValues*  pParams,
    IPortableDeviceValues*  pResults)
{

    HRESULT hr                    = S_OK;
    LPWSTR  pszDestFolderObjectID = NULL;
    CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
    CComPtr<IPortableDevicePropVariantCollection> pMoveResults;
    BOOL    bMoveFailed           = FALSE;
    VARTYPE vt                    = VT_EMPTY;

    if (hr == S_OK)
    {
        hr = pParams->GetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS, &pObjectIDs);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS");
    }

    // Ensure that this is a collection of VT_LPWSTR
    if (hr == S_OK)
    {
        hr = pObjectIDs->GetType(&vt);
        CHECK_HR(hr, "Failed to get the VARTYP of WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS");
        if (hr == S_OK)
        {
            if (vt != VT_LPWSTR)
            {
                hr = E_INVALIDARG;
                CHECK_HR(hr, "WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS is not a collection of VT_LPWSTR");
            }
        }
    }

    if (hr == S_OK)
    {
        hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_MANAGEMENT_DESTINATION_FOLDER_OBJECT_ID, &pszDestFolderObjectID);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_MANAGEMENT_DESTINATION_FOLDER_OBJECT_ID");
    }

    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDevicePropVariantCollection,
                              (VOID**) &pMoveResults);
        CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDevicePropVariantCollection");
    }


    if (hr == S_OK)
    {
        DWORD   cObjects    = 0;
        // Loop through the object list and attempt to move
        hr = pObjectIDs->GetCount(&cObjects);
        CHECK_HR(hr, "Failed to get number of objects to move");

        if (hr == S_OK)
        {
            for(DWORD dwIndex = 0; dwIndex < cObjects; dwIndex++)
            {
                HRESULT hrTemp = S_OK;
                PROPVARIANT pv = {0};

                PropVariantInit(&pv);
                // Get the next Object to move
                hrTemp = pObjectIDs->GetAt(dwIndex, &pv);
                CHECK_HR(hr, "Failed to get next object id at index %d", dwIndex);
                if (hrTemp == S_OK)
                {
                    // Move this object
                    hrTemp = m_pFakeDevice->MoveObject(pv.pwszVal, pszDestFolderObjectID);
                    CHECK_HR(hrTemp, "Failed to move object [%ws] to folder [%ws]", pv.pwszVal, pszDestFolderObjectID);

                    if(FAILED(hrTemp))
                    {
                        bMoveFailed = TRUE;
                    }

                    PROPVARIANT pvResult = {0};

                    PropVariantInit(&pvResult);

                    // Save this result
                    pvResult.vt       = VT_ERROR;
                    pvResult.scode    = hrTemp;
                    hrTemp = pMoveResults->Add(&pvResult);
                    CHECK_HR(hrTemp, "Failed to add result for [%ws] to list of results", pv.pwszVal);

                    PropVariantClear(&pvResult);
                }
                PropVariantClear(&pv);
            }
        }
    }

    // Set the results
    if (hr == S_OK)
    {
        hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_OBJECT_MANAGEMENT_MOVE_RESULTS, pMoveResults);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_MANAGEMENT_MOVE_RESULTS");
    }

    CoTaskMemFree(pszDestFolderObjectID);

    // If an object failed to move, make sure we return S_FALSE
    if ((hr == S_OK) && (bMoveFailed))
    {
        hr = S_FALSE;
    }

    return hr;
}
// Writes a set of properties for all objects.
void WriteContentPropertiesBulk(
    IPortableDevice*    pDevice)
{
    if (pDevice == NULL)
    {
        printf("! A NULL IPortableDevice interface pointer was received\n");
        return;
    }

    HRESULT                                       hr                = S_OK;
    GUID                                          guidContext       = GUID_NULL;
    CSetBulkValuesCallback*                       pCallback         = NULL;
    CComPtr<IPortableDeviceProperties>            pProperties;
    CComPtr<IPortableDevicePropertiesBulk>        pPropertiesBulk;
    CComPtr<IPortableDeviceValues>                pObjectProperties;
    CComPtr<IPortableDeviceContent>               pContent;
    CComPtr<IPortableDeviceValuesCollection>      pPropertiesToWrite;
    CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
    DWORD                                         cObjectIDs        = 0;


    // 1) Get an IPortableDeviceContent interface from the IPortableDevice interface to
    // access the content-specific methods.
    hr = pDevice->Content(&pContent);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
    }

    // 2) Get an IPortableDeviceProperties interface from the IPortableDeviceContent interface
    // to access the property-specific methods.
    if (SUCCEEDED(hr))
    {
        hr = pContent->Properties(&pProperties);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }

    // 3) Check to see if the driver supports BULK property operations by call QueryInterface
    // on the IPortableDeviceProperties interface for IPortableDevicePropertiesBulk
    if (SUCCEEDED(hr))
    {
        hr = pProperties->QueryInterface(IID_PPV_ARGS(&pPropertiesBulk));
        if (FAILED(hr))
        {
            printf("This driver does not support BULK property operations.\n");
        }
    }

    // 4) CoCreate an IPortableDeviceValuesCollection interface to hold the the properties
    // we wish to write.
    if (SUCCEEDED(hr))
    {
        hr = CoCreateInstance(CLSID_PortableDeviceValuesCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_PPV_ARGS(&pPropertiesToWrite));
        if (FAILED(hr))
        {
            printf("! Failed to CoCreate IPortableDeviceValuesCollection for bulk property values, hr = 0x%lx\n", hr);
        }
    }

    // 6) Create an instance of the IPortableDevicePropertiesBulkCallback object.
    if (SUCCEEDED(hr))
    {
        pCallback = new (std::nothrow) CSetBulkValuesCallback();
        if (pCallback == NULL)
        {
            hr = E_OUTOFMEMORY;
            printf("! Failed to allocate CSetBulkValuesCallback, hr = 0x%lx\n", hr);
        }
    }

    // 7) Call our helper function CreateIPortableDevicePropVariantCollectionWithAllObjectIDs
    // to enumerate and create an IPortableDevicePropVariantCollection with the object
    // identifiers needed to perform the bulk operation on.
    if (SUCCEEDED(hr))
    {
        hr = CreateIPortableDevicePropVariantCollectionWithAllObjectIDs(pContent,
                                                                        &pObjectIDs);
    }

    if (SUCCEEDED(hr))
    {
        hr = pObjectIDs->GetCount(&cObjectIDs);
        if (FAILED(hr))
        {
            printf("! Failed to get number of objectIDs from IPortableDevicePropVariantCollection, hr = 0x%lx\n", hr);
        }
    }

    // 8) Iterate through object list and add appropriate IPortableDeviceValues to collection
    if (SUCCEEDED(hr))
    {
        for(DWORD dwIndex = 0; (dwIndex < cObjectIDs) && (hr == S_OK); dwIndex++)
        {
            CComPtr<IPortableDeviceValues>  pValues;
            PROPVARIANT                     pv = {0};

            PropVariantInit(&pv);
            hr = CoCreateInstance(CLSID_PortableDeviceValues,
                                  NULL,
                                  CLSCTX_INPROC_SERVER,
                                  IID_PPV_ARGS(&pValues));
            if (FAILED(hr))
            {
                printf("! Failed to CoCreate CLSID_PortableDeviceValues, hr = 0x%lx\n", hr);
            }

            // Get the Object ID whose properties we will set
            if (hr == S_OK)
            {
                hr = pObjectIDs->GetAt(dwIndex, &pv);
                if (FAILED(hr))
                {
                    printf("! Failed to get next Object ID from list, hr = 0x%lx\n", hr);
                }
            }

            // Save them into the IPortableDeviceValues so the driver knows which object this proeprty set belongs to
            if (hr == S_OK)
            {
                hr = pValues->SetStringValue(WPD_OBJECT_ID, pv.pwszVal);
                if (FAILED(hr))
                {
                    printf("! Failed to set WPD_OBJECT_ID, hr = 0x%lx\n", hr);
                }
            }

            // Set the new values.  In this sample, we attempt to set the name property.
            if (hr == S_OK)
            {
                CAtlStringW strValue;
                strValue.Format(L"NewName%d", dwIndex);

                hr = pValues->SetStringValue(WPD_OBJECT_NAME, strValue.GetString());
                if (FAILED(hr))
                {
                    printf("! Failed to set WPD_OBJECT_NAME, hr = 0x%lx\n", hr);
                }
            }

            // Add this property set to the collection
            if (hr == S_OK)
            {
                hr = pPropertiesToWrite->Add(pValues);
                if (FAILED(hr))
                {
                    printf("! Failed to add values to collection, hr = 0x%lx\n", hr);
                }
            }
            PropVariantClear(&pv);
        }
    }

    // 9) Call QueueSetValuesByObjectList to initialize the Asynchronous
    // property operation.
    if (SUCCEEDED(hr))
    {
        hr = pPropertiesBulk->QueueSetValuesByObjectList(pPropertiesToWrite,
                                                         pCallback,
                                                         &guidContext);
        // 10) Call Start() to actually being the property operation
        if(SUCCEEDED(hr))
        {
            // Cleanup any previously created global event handles.
            if (g_hBulkPropertyOperationEvent != NULL)
            {
                CloseHandle(g_hBulkPropertyOperationEvent);
                g_hBulkPropertyOperationEvent = NULL;
            }

            // In order to create a simpler to follow example we create and wait infinitly
            // for the bulk property operation to complete and ignore any errors.
            // Production code should be written in a more robust manner.
            // Create the global event handle to wait on for the bulk operation
            // to complete.
            g_hBulkPropertyOperationEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
            if (g_hBulkPropertyOperationEvent != NULL)
            {
                // Call Start() to actually being the Asynchronous bulk operation.
                hr = pPropertiesBulk->Start(guidContext);
                if(FAILED(hr))
                {
                    printf("! Failed to start property operation, hr = 0x%lx\n", hr);
                }
            }
            else
            {
                printf("! Failed to create the global event handle to wait on for the bulk operation. Aborting operation.\n");
            }
        }
        else
        {
            printf("! QueueSetValuesByObjectList Failed, hr = 0x%lx\n", hr);
        }
    }

    // In order to create a simpler to follow example we will wait infinitly for the operation
    // to complete and ignore any errors.  Production code should be written in a more
    // robust manner.
    if (SUCCEEDED(hr))
    {
        if (g_hBulkPropertyOperationEvent != NULL)
        {
            WaitForSingleObject(g_hBulkPropertyOperationEvent, INFINITE);
        }
    }

    if (pCallback != NULL)
    {
        pCallback->Release();
        pCallback = NULL;
    }

    // Cleanup any created global event handles before exiting..
    if (g_hBulkPropertyOperationEvent != NULL)
    {
        CloseHandle(g_hBulkPropertyOperationEvent);
        g_hBulkPropertyOperationEvent = NULL;
    }
}
/**
 *  This method is called when we receive a WPD_COMMAND_CAPABILITIES_GET_FUNCTIONAL_OBJECTS
 *  command.  It is sent when the caller is interesting in finding the object IDs for all
 *  functional objects belonging to the specified functional category.
 *  Note: the number of functional objects is expected to be very small (less than 8 for the
 *  whole device).
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORY - a GUID value containing the category
 *    the caller is looking for.  If the value is WPD_FUNCTIONAL_CATEGORY_ALL, then the driver
 *    must return all functional objects, no matter which category they belong to.
 *
 *  The driver should:
 *  - Return an IPortableDevicePropVariantCollection (of type VT_LPWSTR) in
 *      WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_OBJECTS, containing
 *      the ids of the functional objects who belong to the specified functional category.
 *      If there are no objects in the specified category, the driver should return an
 *      empty collection.
 */
HRESULT WpdCapabilities::OnGetFunctionalObjects(
    _In_ IPortableDeviceValues*  pParams,
    _In_ IPortableDeviceValues*  pResults)
{
    HRESULT hr                     = S_OK;
    GUID    guidFunctionalCategory = GUID_NULL;
    CComPtr<IPortableDevicePropVariantCollection> pFunctionalObjects;

    // First get ALL parameters for this command.  If we cannot get ALL parameters
    // then E_INVALIDARG should be returned and no further processing should occur.

    // Get the functional category whose functional object identifiers have been requested
    if (hr == S_OK)
    {
        hr = pParams->GetGuidValue(WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORY, &guidFunctionalCategory);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORY");
    }

    // CoCreate a collection to store the supported functional object identifiers.
    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDevicePropVariantCollection,
                              (VOID**) &pFunctionalObjects);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection");
    }

    // Add the supported functional object identifiers for the specified functional
    // category to the collection.
    if (hr == S_OK)
    {
        PROPVARIANT pv = {0};
        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 (hr == S_OK)
        {
            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 STORAGE_OBJECT_ID to the functional object identifiers collection
        if (hr == S_OK)
        {
            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");
            }
        }
    }

    // Set the WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_OBJECTS value in the results.
    if (hr == S_OK)
    {
        hr = pResults->SetIUnknownValue(WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_OBJECTS, pFunctionalObjects);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_OBJECTS");
    }

    return hr;
}
// Reads properties for the user specified object.
void ReadContentProperties(
    IPortableDevice*    pDevice)
{
    if (pDevice == NULL)
    {
        printf("! A NULL IPortableDevice interface pointer was received\n");
        return;
    }

    HRESULT                               hr               = S_OK;
    WCHAR                                 szSelection[81]  = {0};
    CComPtr<IPortableDeviceProperties>    pProperties;
    CComPtr<IPortableDeviceValues>        pObjectProperties;
    CComPtr<IPortableDeviceContent>       pContent;
    CComPtr<IPortableDeviceKeyCollection> pPropertiesToRead;

    // Prompt user to enter an object identifier on the device to read properties from.
    printf("Enter the identifer of the object you wish to read properties from.\n>");
    hr = StringCbGetsW(szSelection,sizeof(szSelection));
    if (FAILED(hr))
    {
        printf("An invalid object identifier was specified, aborting property reading\n");
    }

    // 1) Get an IPortableDeviceContent interface from the IPortableDevice interface to
    // access the content-specific methods.
    if (SUCCEEDED(hr))
    {
        hr = pDevice->Content(&pContent);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }

    // 2) Get an IPortableDeviceProperties interface from the IPortableDeviceContent interface
    // to access the property-specific methods.
    if (SUCCEEDED(hr))
    {
        hr = pContent->Properties(&pProperties);
        if (FAILED(hr))
        {
            printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
        }
    }

    // 3) CoCreate an IPortableDeviceKeyCollection interface to hold the the property keys
    // we wish to read.
	//<SnippetContentProp1>
    hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_PPV_ARGS(&pPropertiesToRead));
    if (SUCCEEDED(hr))
    {
        // 4) Populate the IPortableDeviceKeyCollection with the keys we wish to read.
        // NOTE: We are not handling any special error cases here so we can proceed with
        // adding as many of the target properties as we can.
        if (pPropertiesToRead != NULL)
        {
            HRESULT hrTemp = S_OK;
            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_PARENT_ID);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_PARENT_ID to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_NAME);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_NAME to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_PERSISTENT_UNIQUE_ID);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_PERSISTENT_UNIQUE_ID to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_FORMAT);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_FORMAT to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }

            hrTemp = pPropertiesToRead->Add(WPD_OBJECT_CONTENT_TYPE);
            if (FAILED(hrTemp))
            {
                printf("! Failed to add WPD_OBJECT_CONTENT_TYPE to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
            }
        }
    }
	//</SnippetContentProp1>
	// 5) Call GetValues() passing the collection of specified PROPERTYKEYs.
	//<SnippetContentProp2>
    if (SUCCEEDED(hr))
    {
        hr = pProperties->GetValues(szSelection,         // The object whose properties we are reading
                                    pPropertiesToRead,   // The properties we want to read
                                    &pObjectProperties); // Driver supplied property values for the specified object
        if (FAILED(hr))
        {
            printf("! Failed to get all properties for object '%ws', hr= 0x%lx\n", szSelection, hr);
        }
    }
	//</SnippetContentProp2>
    // 6) Display the returned property values to the user
    if (SUCCEEDED(hr))
    {
        DisplayStringProperty(pObjectProperties, WPD_OBJECT_PARENT_ID,            L"WPD_OBJECT_PARENT_ID");
        DisplayStringProperty(pObjectProperties, WPD_OBJECT_NAME,                 L"WPD_OBJECT_NAME");
        DisplayStringProperty(pObjectProperties, WPD_OBJECT_PERSISTENT_UNIQUE_ID, L"WPD_OBJECT_PERSISTENT_UNIQUE_ID");
        DisplayGuidProperty  (pObjectProperties, WPD_OBJECT_CONTENT_TYPE,         L"WPD_OBJECT_CONTENT_TYPE");
        DisplayGuidProperty  (pObjectProperties, WPD_OBJECT_FORMAT,               L"WPD_OBJECT_FORMAT");
    }
}
/**
 *  This method is called when we receive a WPD_COMMAND_CAPABILITIES_GET_SUPPORTED_CONTENT_TYPES
 *  command.  This message is sent when the client needs to know the possible content types supported
 *  by the specified functional category.
 *  If the driver has multiple functional objects that may support different content types,
 *  the driver should simply merge them together and report all possible types in one list here.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORY - a GUID value containing the functional category
 *    whose content types the caller is interested in.  If the value is WPD_FUNCTIONAL_CATEGORY_ALL, then the driver
 *    must return a list of all content types supported by the device.
 *
 *  The driver should:
 *  - Return an IPortableDevicePropVariantCollection (of type VT_CLSID) in
 *      WPD_PROPERTY_CAPABILITIES_CONTENT_TYPES, containing
 *      the content types supported by the specified functional category.
 *      If there are no objects in the specified category, the driver should return an
 *      empty collection.
 */
HRESULT WpdCapabilities::OnGetSupportedContentTypes(
    _In_ IPortableDeviceValues*  pParams,
    _In_ IPortableDeviceValues*  pResults)
{
    HRESULT hr                     = S_OK;
    GUID    guidFunctionalCategory = GUID_NULL;
    CComPtr<IPortableDevicePropVariantCollection> pContentTypes;

    // First get ALL parameters for this command.  If we cannot get ALL parameters
    // then E_INVALIDARG should be returned and no further processing should occur.

    // Get the functional category whose supported content types have been requested
    if (hr == S_OK)
    {
        hr = pParams->GetGuidValue(WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORY, &guidFunctionalCategory);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_CAPABILITIES_FUNCTIONAL_CATEGORY");
    }

    // CoCreate a collection to store the supported content types.
    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDevicePropVariantCollection,
                              (VOID**) &pContentTypes);
        CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDevicePropVariantCollection");
    }

    // Add the supported content types for the specified functional
    // category to the collection.
    if (hr == S_OK)
    {
        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");
            }
        }
    }

    // Set the WPD_PROPERTY_CAPABILITIES_CONTENT_TYPES value in the results.
    if (hr == S_OK)
    {
        hr = pResults->SetIUnknownValue(WPD_PROPERTY_CAPABILITIES_CONTENT_TYPES, pContentTypes);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_CAPABILITIES_CONTENT_TYPES");
    }

    return hr;
}
Exemple #24
0
HRESULT CMyAddin::InstallInterface(IExchExtCallback		*lpExchangeCallback)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	try
	{
		CString csTitle = APP_NAME; // This will be the display-name of the toolbar
		HBITMAP hBmp;

		// First we need to get the active Explorer, you could see this as the active window (it's more to it but let's keep it at that for now)
		Outlook::_ExplorerPtr spExplorer = m_OLAppPtr->ActiveExplorer();
		if (spExplorer == NULL)
		{
			return S_FALSE;
		}

		// Then we need to have a pointer to the commandbars, that is the toolbars in the UI
		Office::_CommandBarsPtr spCmdBars = spExplorer->CommandBars;
		if (spCmdBars == NULL)
		{
			return S_FALSE;
		}

		try 
		{ 
			CComVariant vName(csTitle); // This is the caption of the toolbar
			CComVariant vTemp(TRUE);	
			CComPtr <Office::CommandBar> spToolbar;	
			
			CComVariant vPos(1); 
			//CComVariant vTemp(VARIANT_TRUE); 		
			CComVariant vEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);

			/*spToolbar = spCmdBars->Add(vName,		// Caption
									   vtMissing,   // <ignore this for now>
									   vtMissing,   // <ignore this for now>
									   vTemp);      // The toolbar should be temporary, 
													// that way we have to add it every time we*/
			//spToolbar = spCmdBars->Add(vName,		// Caption
			//						   vPos,   // <ignore this for now>
			//						   vEmpty,   // <ignore this for now>
			//						   vTemp);      // The toolbar should be temporary, 
													// that way we have to add it every time we

			CComPtr <Office::CommandBarControl>  pButton	  = NULL; 
			CComPtr <Office::CommandBarControls> pBarControls = NULL; 

			//pBarControls = spToolbar->GetControls();

			/*m_pToolBar = (Office::CommandBarControlPtr)(pBarControls->Add((long)Office::msoBarFloating, //msoControlButton, 
																	   vtMissing, 
																	   vtMissing, 
																	   vtMissing, 
																	   vTemp));*/			
			
			// get the outlok Context Menu. for this enumerate all the command bars for "Context Menu" command bar			
			CComPtr<Office::CommandBar> pTempBar;
			for(long i = 0; i < spCmdBars->Count ; i++)
			{			
				CComVariant vItem(i+1);		 //zero based index
				pTempBar=NULL;
				spCmdBars->get_Item(vItem,&pTempBar);				
				if((pTempBar) && (!wcscmp(CString(APP_NAME).AllocSysString(),pTempBar->Name)))
				{
					return S_FALSE;
				}		
			}



			m_pToolBar = (Office::CommandBarPtr)(spCmdBars->Add(APP_NAME, vPos, /*Office::msoBarFloating,*/ vtMissing, vTemp));
			pButton = (Office::CommandBarControlPtr)m_pToolBar->Controls->Add(Office::msoControlButton,
																	  vtMissing, vtMissing, vtMissing, vTemp);

			pButton->Caption  = APP_NAME;
			pButton->OnAction = "MyButtonsAction";

			BOOL bSetImage = TRUE;
			// I've set this to FALSE, but if you want an image to appear on the button, 
			// you will need to have an image in the resources.
			// The only drawback of this is that there is only one way of 
			// putting an image on the button, and that is by going through the 
			// clipboard. And by doing so, the contents of the clipboard will be
			// lost, unless you implement some logic to store the clipboard-data
			// before doing this and then restoring the data once the image is on 
			// the button.
			if (bSetImage)
			{
				UINT uiBitmapId = 0;
				CComQIPtr <Office::_CommandBarButton> spCmdButton(pButton);

				// to set a bitmap to a button, load a 32x32 bitmap
				// and copy it to clipboard. Call CommandBarButton's PasteFace()
				// to copy the bitmap to the button face. to use
				// Outlook's set of predefined bitmap, set button's FaceId to 	
				// the button whose bitmap you want to use
				
				hBmp =(HBITMAP)::LoadImage(AfxGetInstanceHandle(),
												   MAKEINTRESOURCE(IDB_BITMAP_PHONE),
												   IMAGE_BITMAP,
												   0,
												   0,
												   LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT);

				if (hBmp)
				{					
					// put bitmap into Clipboard
					::OpenClipboard(NULL);
					::EmptyClipboard();
					::SetClipboardData(CF_BITMAP, (HANDLE)hBmp);
					::CloseClipboard();
					::DeleteObject(hBmp);	

					// set style before setting bitmap
					spCmdButton->PutStyle(Office::msoButtonIconAndCaption);
					if (FAILED(spCmdButton->PasteFace()))
					{
						TRACE("Failed to paste face to button\n");
					}

					
				}/* else {
					char serr[50];
					DWORD err = GetLastError();
					ltoa(err, serr, 10);
					MessageBox(NULL, serr, "error", MB_OK);
				}*/
			}
			// With the button physically added to the toolbar, we just need to 
			// create an object of COutlookButton to sink it's events.
			m_pMyButton = new COutlookButton(pButton);
			m_pMyButton->m_OLAppPtr = m_OLAppPtr;

			// The only thing left to do is to make the toolbar visible.
			//spToolbar->PutVisible(VARIANT_TRUE); 
			LoadToolbarSettings();
		} 
		catch(...)
		{
		}


		// Add menu item

		_bstr_t bstrNewMenuText(CString(APP_NAME).AllocSysString());
		CComPtr < Office::CommandBarControls> spCmdCtrls;
		CComPtr < Office::CommandBarControls> spCmdBarCtrls; 
		CComPtr < Office::CommandBarPopup> spCmdPopup;
		CComPtr < Office::CommandBarControl> spCmdCtrl;
		CComPtr < Office::CommandBar> spCmdBar;

		// get CommandBar that is Outlook's main menu
		HRESULT hr = spCmdBars->get_ActiveMenuBar(&spCmdBar); 
		if (FAILED(hr))
			return S_FALSE; //hr;
		// get menu as CommandBarControls 
		spCmdCtrls = spCmdBar->GetControls(); 
		ATLASSERT(spCmdCtrls);

		// we want to add a menu entry to Outlook's 6th(Tools) menu     //item
		CComVariant vItem(5);
		spCmdCtrl= spCmdCtrls->GetItem(vItem);
		ATLASSERT(spCmdCtrl);
        
		IDispatchPtr spDisp;
		spDisp = spCmdCtrl->GetControl(); 
        
		// a CommandBarPopup interface is the actual menu item
		CComQIPtr < Office::CommandBarPopup> ppCmdPopup(spDisp);  
		ATLASSERT(ppCmdPopup);
            
		spCmdBarCtrls = ppCmdPopup->GetControls();
		ATLASSERT(spCmdBarCtrls);
        
		CComVariant vMenuType(1); // type of control - menu
		CComVariant vMenuPos(6);  
		CComVariant vMenuEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);
		CComVariant vMenuShow(VARIANT_TRUE); // menu should be visible
		CComVariant vMenuTemp(VARIANT_TRUE); // menu is temporary        
    
        
		CComPtr < Office::CommandBarControl> spNewMenu;
		// now create the actual menu item and add it
		spNewMenu = spCmdBarCtrls->Add(vMenuType, vMenuEmpty, vMenuEmpty, 
										   vMenuEmpty, vMenuTemp); 
		ATLASSERT(spNewMenu);
            
		spNewMenu->PutCaption(bstrNewMenuText);
		spNewMenu->PutEnabled(VARIANT_TRUE);
		spNewMenu->PutVisible(VARIANT_TRUE); 
		spNewMenu->OnAction = "MyButtonsAction";
    
		//we'd like our new menu item to look cool and display
		// an icon. Get menu item  as a CommandBarButton
		CComQIPtr < Office::_CommandBarButton> spCmdMenuButton(spNewMenu);
		ATLASSERT(spCmdMenuButton);
		spCmdMenuButton->PutStyle(Office::msoButtonIconAndCaption);
    
		// we want to use the same toolbar bitmap for menuitem too.
		// we grab the CommandBarButton interface so we can add
		// a bitmap to it through PasteFace().
		spCmdMenuButton->PasteFace(); 


		// Empty whatever we put in the clipboard
		::OpenClipboard(NULL);
		::EmptyClipboard();
		::CloseClipboard();

		// With the button physically added to the toolbar, we just need to 
		// create an object of COutlookButton to sink it's events.
		m_pMyMenuItem = new COutlookButton(spNewMenu);
		m_pMyMenuItem->m_OLAppPtr = m_OLAppPtr;

		// show the menu        
		spNewMenu->PutVisible(VARIANT_TRUE); 
   }
   catch(...)
   {
   }

   return S_FALSE;
}
/**
 *  This method is called when we receive a WPD_COMMAND_OBJECT_MANAGEMENT_DELETE_OBJECTS
 *  command.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS: the ObjectIDs, indicating which objects to delete.  These may
 *      contain children.
 *  - WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_OPTIONS: Flag parameter indicating delete options. Must be one
 *                  of the following:
 *                 - PORTABLE_DEVICE_DELETE_NO_RECURSION - Deletes the
 *                          object only.  This should fail if children exist.
 *                 - PORTABLE_DEVICE_DELETE_WITH_RECURSION - Deletes this
 *                          object and all children.
 *
 *  The driver should:
 *  - If the flag is PORTABLE_DEVICE_DELETE_NO_RECURSION the driver should delete the
 *    specified object only.  If the object still has children the driver should not delete
 *    the object and instead return HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION).
 *  - If the flag is PORTABLE_DEVICE_DELETE_WITH_RECURSION the driver should delete the
 *    specified object and all of its children.
 *  - Fill out the operation results in WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS.  It contains an IPortableDevicePropVariantCollection of
 *    VT_ERROR values indicating the success or failure of the operation for that element.
 *    Order is implicit, i.e. the first element of WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS corresponds to the first element of WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS and so on.
 *  - The driver should return:
 *      - S_OK if all objects were deleted successfully.
 *      - S_FALSE if any object delete failed.
 *      - An error return indicates that the driver did not delete any objects, and
 *        WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS is ignored.
 */
HRESULT WpdObjectManagement::OnDelete(
    IPortableDeviceValues*  pParams,
    IPortableDeviceValues*  pResults)
{

    HRESULT hr              = S_OK;
    DWORD   dwOptions       = PORTABLE_DEVICE_DELETE_NO_RECURSION;
    BOOL    bDeleteFailed   = FALSE;
    CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
    CComPtr<IPortableDevicePropVariantCollection> pDeleteResults;
    CComPtr<IPortableDeviceValues> pEventParams;
    VARTYPE vt              = VT_EMPTY;

    if (hr == S_OK)
    {
        hr = pParams->GetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS, &pObjectIDs);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS");
    }

    // Ensure that this is a collection of VT_LPWSTR
    if (hr == S_OK)
    {
        hr = pObjectIDs->GetType(&vt);
        CHECK_HR(hr, "Failed to get the VARTYP of WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS");
        if (hr == S_OK)
        {
            if (vt != VT_LPWSTR)
            {
                hr = E_INVALIDARG;
                CHECK_HR(hr, "WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS is not a collection of VT_LPWSTR");
            }
        }
    }

    if (hr == S_OK)
    {
        hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_OPTIONS, &dwOptions);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_OPTIONS");
    }

    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDevicePropVariantCollection,
                              (VOID**) &pDeleteResults);
        CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDevicePropVariantCollection");
    }


    if (hr == S_OK)
    {
        DWORD   cObjects    = 0;
        // Loop through the object list and attempt to delete
        hr = pObjectIDs->GetCount(&cObjects);
        CHECK_HR(hr, "Failed to get number of objects to delete");

        if (hr == S_OK)
        {
            for(DWORD dwIndex = 0; dwIndex < cObjects; dwIndex++)
            {
                HRESULT hrTemp = S_OK;
                PROPVARIANT pv = {0};

                PropVariantInit(&pv);
                // Get the next Object to delete
                hr = pObjectIDs->GetAt(dwIndex, &pv);
                CHECK_HR(hr, "Failed to get next object id at index %d", dwIndex);
                if (hr == S_OK)
                {
                    pEventParams = NULL;
                    // Get the object properties used for sending the event.  Ignore errors (these are expected in some cases
                    // e.g. app is sending object ID that doesn't exist), since this relates to the event, not the delete operation,
                    // and we return results for the delete (an error posting the event is non-fatal).
                    hrTemp = m_pFakeDevice->GetObjectPropertiesForEvent(pv.pwszVal, &pEventParams);
                    CHECK_HR(hrTemp, "Failed to get properties for event on object %ws", pv.pwszVal);

                    HRESULT     hrDelete = S_OK;
                    PROPVARIANT pvResult = {0};

                    PropVariantInit(&pvResult);

                    hrDelete = m_pFakeDevice->DeleteObject(dwOptions, pv.pwszVal);
                    CHECK_HR(hrDelete, "Failed to delete object [%ws]", pv.pwszVal);

                    if(FAILED(hrDelete))
                    {
                        bDeleteFailed = TRUE;
                    }

                    // Save this result
                    pvResult.vt       = VT_ERROR;
                    pvResult.scode    = hrDelete;
                    hrTemp = pDeleteResults->Add(&pvResult);
                    PropVariantClear(&pvResult);
                    CHECK_HR(hrTemp, "Failed to add result for [%ws] to list of results", pv.pwszVal);

                    if ((hrDelete == S_OK) && (hrTemp == S_OK))
                    {
                        HRESULT hrEvent = S_OK;
                        // Set the event-specific parameters
                        hrEvent = pEventParams->SetGuidValue(WPD_EVENT_PARAMETER_EVENT_ID, WPD_EVENT_OBJECT_REMOVED);
                        CHECK_HR(hrEvent, "Failed to add WPD_EVENT_PARAMETER_EVENT_ID");

                        // Send the Event
                        if (hrEvent == S_OK)
                        {
                            PostWpdEvent(pParams, pEventParams);
                        }
                    }
                    PropVariantClear(&pv);
                }
                else
                {
                    break;
                }
            }
        }
    }

    // Set the results
    if (hr == S_OK)
    {
        hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS, pDeleteResults);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS");
    }

    // If an object failed to delete, make sure we return S_FALSE
    if ((hr == S_OK) && (bDeleteFailed))
    {
        hr = S_FALSE;
    }

    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;
}
/**
 *  This method is called when we receive a WPD_COMMAND_OBJECT_MANAGEMENT_COPY_OBJECTS
 *  command.
 *
 * This command will copy the specified objects to the destination folder.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS : the ObjectIDs, indicating which objects to copy.  These may
 *      be folder objects.
 *  - WPD_PROPERTY_OBJECT_MANAGEMENT_DESTINATION_FOLDER_OBJECT_ID: Indicates the destination folder for the copy operation.
 *
 *  The driver should:
 *  - Attempt to copy the object specified in WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS to the folder specified in
 *    WPD_PROPERTY_OBJECT_MANAGEMENT_DESTINATION_FOLDER_OBJECT_ID.
 * - Fill out the operation results in WPD_PROPERTY_OBJECT_MANAGEMENT_COPY_RESULTS.  It contains an IPortableDevicePropVariantCollection of
 *   VT_ERROR values indicating the success or failure of the operation for that element.
 *   Order is implicit, i.e. the first element of WPD_PROPERTY_OBJECT_MANAGEMENT_COPY_RESULTS corresponds to the first element of WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS and so on.
 *  - The driver should return:
 *      - S_OK if all objects were copied successfully.
 *      - S_FALSE if any object copy failed.
 *      - An error return indicates that the driver did not copy any objects, and
 *        WPD_PROPERTY_OBJECT_MANAGEMENT_COPY_RESULTS is ignored.
 */
HRESULT WpdObjectManagement::OnCopy(
    IPortableDeviceValues*  pParams,
    IPortableDeviceValues*  pResults)
{

    HRESULT hr                    = S_OK;
    LPWSTR  pszDestFolderObjectID = NULL;
    CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
    CComPtr<IPortableDevicePropVariantCollection> pCopyResults;
    BOOL    bCopyFailed           = FALSE;
    VARTYPE vt                    = VT_EMPTY;

    if (hr == S_OK)
    {
        hr = pParams->GetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS, &pObjectIDs);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS");
    }

    // Ensure that this is a collection of VT_LPWSTR
    if (hr == S_OK)
    {
        hr = pObjectIDs->GetType(&vt);
        CHECK_HR(hr, "Failed to get the VARTYP of WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS");
        if (hr == S_OK)
        {
            if (vt != VT_LPWSTR)
            {
                hr = E_INVALIDARG;
                CHECK_HR(hr, "WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS is not a collection of VT_LPWSTR");
            }
        }
    }

    if (hr == S_OK)
    {
        hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_MANAGEMENT_DESTINATION_FOLDER_OBJECT_ID, &pszDestFolderObjectID);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_MANAGEMENT_DESTINATION_FOLDER_OBJECT_ID");
    }

    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDevicePropVariantCollection,
                              (VOID**) &pCopyResults);
        CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDevicePropVariantCollection");
    }


    if (hr == S_OK)
    {
        DWORD   cObjects    = 0;
        // Loop through the object list and attempt to copy
        hr = pObjectIDs->GetCount(&cObjects);
        CHECK_HR(hr, "Failed to get number of objects to copy");

        if (hr == S_OK)
        {
            for(DWORD dwIndex = 0; dwIndex < cObjects; dwIndex++)
            {
                CComPtr<IPortableDeviceValues> pEventParams;
                LPWSTR  pszNewObjectID = NULL;
                HRESULT hrTemp = S_OK;
                PROPVARIANT pv = {0};

                PropVariantInit(&pv);
                // Get the next Object to copy
                hrTemp = pObjectIDs->GetAt(dwIndex, &pv);
                CHECK_HR(hr, "Failed to get next object id at index %d", dwIndex);
                if (hrTemp == S_OK)
                {
                    // Copy this object
                    hrTemp = m_pFakeDevice->CopyObject(pv.pwszVal, pszDestFolderObjectID, &pszNewObjectID);
                    CHECK_HR(hrTemp, "Failed to copy object [%ws] to folder [%ws]", pv.pwszVal, pszDestFolderObjectID);

                    if(FAILED(hrTemp))
                    {
                        bCopyFailed = TRUE;
                    }

                    PROPVARIANT pvResult = {0};

                    PropVariantInit(&pvResult);

                    // Save this result
                    pvResult.vt       = VT_ERROR;
                    pvResult.scode    = hrTemp;
                    hrTemp = pCopyResults->Add(&pvResult);
                    CHECK_HR(hrTemp, "Failed to add result for [%ws] to list of results", pv.pwszVal);

                    PropVariantClear(&pvResult);

                    if (hrTemp == S_OK)
                    {
                        // Send the event
                        // Get the object properties used for sending the event
                        hrTemp = m_pFakeDevice->GetObjectPropertiesForEvent(pszNewObjectID, &pEventParams);
                        CHECK_HR(hrTemp, "Failed to get properties for event on object %ws", pszNewObjectID);
                        if (hrTemp == S_OK)
                        {
                            // Set the event-specific parameters
                            hrTemp = pEventParams->SetGuidValue(WPD_EVENT_PARAMETER_EVENT_ID, WPD_EVENT_OBJECT_ADDED);
                            CHECK_HR(hrTemp, "Failed to add WPD_EVENT_PARAMETER_EVENT_ID");

                            // Send the Event
                            if (hrTemp == S_OK)
                            {
                                PostWpdEvent(pParams, pEventParams);
                            }
                        }
                    }

                }

                if (pszNewObjectID != NULL)
                {
                    CoTaskMemFree(pszNewObjectID);
                    pszNewObjectID = NULL;
                }

                PropVariantClear(&pv);
            }
        }
    }

    // Set the results
    if (hr == S_OK)
    {
        hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_OBJECT_MANAGEMENT_COPY_RESULTS, pCopyResults);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_MANAGEMENT_COPY_RESULTS");
    }

    CoTaskMemFree(pszDestFolderObjectID);

    // If an object failed to copy, make sure we return S_FALSE
    if ((hr == S_OK) && (bCopyFailed))
    {
        hr = S_FALSE;
    }

    return hr;
}
HRESULT FakeContactsService::GetMethodAttributes(
    REFGUID                Method,
    __out   IPortableDeviceValues* pAttributes)
{
    HRESULT hr = S_OK;
    CComPtr<IPortableDeviceKeyCollection> pParameters;

    if (pAttributes == NULL)
    {
        hr = E_POINTER;
        CHECK_HR(hr, "Cannot have NULL parameter");
        return hr;
    }

    // CoCreate a collection for specifying the method parameters.
    hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_IPortableDeviceKeyCollection,
                          (VOID**) &pParameters);
    CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceKeyCollection");

    // Add the method attributes to this collection
    if (Method == METHOD_FullEnumSyncSvc_BeginSync)
    {
        if (hr == S_OK)
        {
            hr = pAttributes->SetStringValue(WPD_METHOD_ATTRIBUTE_NAME, L"BeginSync");
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_NAME");
        }

        if (hr == S_OK)
        {
            hr = pAttributes->SetUnsignedIntegerValue(WPD_METHOD_ATTRIBUTE_ACCESS, WPD_COMMAND_ACCESS_READWRITE);
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_ACCESS");
        }

        if (hr == S_OK)
        {
            // no parameters, set empty collection
            hr = pAttributes->SetIPortableDeviceKeyCollectionValue(WPD_METHOD_ATTRIBUTE_PARAMETERS, pParameters);
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_PARAMETERS");
        }

        if (hr == S_OK)
        {
            // no associated format, set GUID_NULL
            hr = pAttributes->SetGuidValue(WPD_METHOD_ATTRIBUTE_ASSOCIATED_FORMAT, GUID_NULL);
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_ASSOCIATED_FORMAT");
        }

    }
    else if (Method == METHOD_FullEnumSyncSvc_EndSync)
    {
        if (hr == S_OK)
        {
            hr = pAttributes->SetStringValue(WPD_METHOD_ATTRIBUTE_NAME, L"EndSync");
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_NAME");
        }

        if (hr == S_OK)
        {
            hr = pAttributes->SetUnsignedIntegerValue(WPD_METHOD_ATTRIBUTE_ACCESS, WPD_COMMAND_ACCESS_READWRITE);
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_ACCESS");
        }

        if (hr == S_OK)
        {
            // no parameters, set empty collection
            hr = pAttributes->SetIPortableDeviceKeyCollectionValue(WPD_METHOD_ATTRIBUTE_PARAMETERS, pParameters);
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_PARAMETERS");
        }

        if (hr == S_OK)
        {
            // no associated format, set GUID_NULL
            hr = pAttributes->SetGuidValue(WPD_METHOD_ATTRIBUTE_ASSOCIATED_FORMAT, GUID_NULL);
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_ASSOCIATED_FORMAT");
        }
    }
    else if (Method == MyCustomMethod)
    {
        if (hr == S_OK)
        {
            hr = pAttributes->SetStringValue(WPD_METHOD_ATTRIBUTE_NAME, L"CustomMethod");
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_NAME");
        }

        if (hr == S_OK)
        {
            hr = pAttributes->SetUnsignedIntegerValue(WPD_METHOD_ATTRIBUTE_ACCESS, WPD_COMMAND_ACCESS_READWRITE);
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_ACCESS");
        }

        if (hr == S_OK)
        {
            // Set the supported parameters
            for (size_t i=0; i<ARRAYSIZE(g_MethodParameters); i++)
            {
                pParameters->Add(*(g_MethodParameters[i].pKey));
            }

            hr = pAttributes->SetIPortableDeviceKeyCollectionValue(WPD_METHOD_ATTRIBUTE_PARAMETERS, pParameters);
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_PARAMETERS");
        }

        if (hr == S_OK)
        {
            // no associated format, set GUID_NULL
            hr = pAttributes->SetGuidValue(WPD_METHOD_ATTRIBUTE_ASSOCIATED_FORMAT, GUID_NULL);
            CHECK_HR(hr, "Failed to set WPD_METHOD_ATTRIBUTE_ASSOCIATED_FORMAT");
        }
    }
    else
    {
        hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
        CHECK_HR(hr, "Unknown method %ws received",CComBSTR(Method));
    }

    return hr;
}
Exemple #29
0
/*******************************************************************************
  Function Name  : vPopulateGraphControl
  Input(s)       : -
  Output         : -
  Functionality  : This function initializes graph control with list of elements
                   This function will be called from init and during connect.
  Member of      : CGraphLeftView
  Author(s)      : Raja N
  Date Created   : 09/12/2004
  Modifications  : Raja N on 11.03.2005
                   Added channel information to statistics parameters. This will
                   be used in report generation
                   Arunkumar K on 25.07.2011
                   Commented the ClearGraph() function.
*******************************************************************************/
void CGraphLeftView::vPopulateGraphControl()
{
    if( m_pDMGraphCtrl != NULL )
    {
        // Get Element List from Main Frame
        CGraphList* podList = NULL;
        CGraphChildFrame* pParentWnd = NULL;
        pParentWnd = (CGraphChildFrame*)pomGetParentWindow();

        if (pParentWnd != NULL)
        {
            podList = pParentWnd->pGetSignalListDetails();
        }
        else
        {
            ASSERT(FALSE);
        }

        CGraphElement odTemp;

        if ( podList != NULL )
        {
            UINT unMsgID = 0;
            CString omStrName;
            int nItemCount  = (int)podList->m_omElementList.GetSize();
            // Get Buffer Size
            int nBufferSize = podList->m_odGraphParameters.m_nBufferSize;
            CComPtr<IDMGraphCollection> spGraphCollection;
            HRESULT hr = m_pDMGraphCtrl->get_Elements(&spGraphCollection);

            if(FAILED(hr))
            {
                return;
            }

            // Add items to the list
            for ( int nIndex = 0; nIndex < nItemCount; nIndex++ )
            {
                odTemp = podList->m_omElementList[ nIndex ];
                CComPtr<IDispatch> spDispatch;
                //adds to the end and makes it selected
                hr = spGraphCollection->Add(&spDispatch);
                CComPtr<IDMGraphElement> spElement;
                hr = GetCurrentElement(m_pDMGraphCtrl, &spElement);

                // Insert element name
                // If this is stat parameter then append the channel ID
                // prefix with the name
                if ( odTemp.m_nValueType == eSTAT_PARAM )
                {
                    CString omStrChannel;
                    omStrChannel.Format( defSTR_CHANNEL_NAME_FORMAT,
                                         defSTR_CHANNEL_NAME,
                                         odTemp.m_nFrameFormat );
                    // Prefix channel information with the stat
                    // parameter
                    omStrChannel += defSPACE_STR + odTemp.m_omStrElementName;
                    _bstr_t bstrChannel = omStrChannel;
                    spElement->put_Name(bstrChannel.GetBSTR());
                }
                else
                {
                    // Add only the Signal name
                    _bstr_t bstrElementName = odTemp.m_omStrElementName;
                    spElement->put_Name(bstrElementName.GetBSTR());
                }

                // Insert Line Color
                spElement->put_LineColor((OLE_COLOR)odTemp.m_nLineColor);
                // Insert Line Type
                spElement->put_LineType((LineType)odTemp.m_nLineType);
                // Sample Point Type
                spElement->put_PointSymbol((SymbolType)odTemp.m_nPointType);
                // Set The Symbol Type to Sold. Hardcoded
                spElement->put_SolidPoint(VARIANT_TRUE);
                // Sample point type
                spElement->put_PointColor((OLE_COLOR)odTemp.m_nPointColor);
                // Visiblity param
                spElement->put_Show(odTemp.m_bVisible  ? VARIANT_TRUE : VARIANT_FALSE);
            }

            // Set the last item as Selected
            m_omSignalList.SetItemState( nItemCount - 1,
                                         LVIS_SELECTED | LVIS_FOCUSED,
                                         LVIS_SELECTED | LVIS_FOCUSED );
        }
    }
}
/**
 *  This method is called when we receive a WPD_COMMAND_OBJECT_MANAGEMENT_DELETE_OBJECTS
 *  command.
 *
 *  The parameters sent to us are:
 *  - WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS: the ObjectIDs, indicating which objects to delete.  These may
 *      contain children.
 *  - WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_OPTIONS: Flag parameter indicating delete options. Must be one
 *                  of the following:
 *                 - PORTABLE_DEVICE_DELETE_NO_RECURSION - Deletes the
 *                          object only.  This should fail if children exist.
 *                 - PORTABLE_DEVICE_DELETE_WITH_RECURSION - Deletes this
 *                          object and all children.
 *
 *  The driver should:
 *  - If the flag is PORTABLE_DEVICE_DELETE_NO_RECURSION the driver should delete the
 *    specified object only.  If the object still has children the driver should not delete
 *    the object and instead return HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION).
 *  - If the flag is PORTABLE_DEVICE_DELETE_WITH_RECURSION the driver should delete the
 *    specified object and all of its children.
 *  - Fill out the operation results in WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS.  It contains an IPortableDevicePropVariantCollection of
 *    VT_ERROR values indicating the success or failure of the operation for that element.
 *    Order is implicit, i.e. the first element of WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS corresponds to the first element of WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS and so on.
 *  - The driver should return:
 *      - S_OK if all objects were deleted successfully.
 *      - S_FALSE if any object delete failed.
 *      - An error return indicates that the driver did not delete any objects, and
 *        WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS is ignored.
 */
HRESULT WpdObjectManagement::OnDelete(
    _In_    IPortableDeviceValues*  pParams,
    _In_    IPortableDeviceValues*  pResults)
{

    HRESULT hr              = S_OK;
    DWORD   dwOptions       = PORTABLE_DEVICE_DELETE_NO_RECURSION;
    BOOL    bDeleteFailed   = FALSE;
    VARTYPE vt              = VT_EMPTY;

    CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
    CComPtr<IPortableDevicePropVariantCollection> pDeleteResults;
    CComPtr<IPortableDeviceValues>                pEventParams;                

    if (hr == S_OK)
    {
        hr = pParams->GetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS, &pObjectIDs);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS");
    }

    // Ensure that this is a collection of VT_LPWSTR
    if (hr == S_OK)
    {
        hr = pObjectIDs->GetType(&vt);
        CHECK_HR(hr, "Failed to get the VARTYP of WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS");
        if (hr == S_OK)
        {
            if (vt != VT_LPWSTR)
            {
                hr = E_INVALIDARG;
                CHECK_HR(hr, "WPD_PROPERTY_OBJECT_MANAGEMENT_OBJECT_IDS is not a collection of VT_LPWSTR");
            }
        }
    }

    if (hr == S_OK)
    {
        hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_OPTIONS, &dwOptions);
        CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_OPTIONS");
    }

    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDevicePropVariantCollection,
                              (VOID**) &pDeleteResults);
        CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDevicePropVariantCollection");
    }

    if (hr == S_OK)
    {
        hr = CoCreateInstance(CLSID_PortableDeviceValues,
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              IID_IPortableDeviceValues,
                              (VOID**) &pEventParams);
        CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDeviceValues");
    }

    if (hr == S_OK)
    {
        DWORD   cObjects    = 0;
        // Loop through the object list and attempt to delete
        hr = pObjectIDs->GetCount(&cObjects);
        CHECK_HR(hr, "Failed to get number of objects to delete");

        if (hr == S_OK)
        {
            ACCESS_SCOPE Scope = m_pDevice->GetAccessScope(pParams);

            for(DWORD dwIndex = 0; dwIndex < cObjects; dwIndex++)
            {
                HRESULT hrTemp = S_OK;
                PROPVARIANT pv = {0};

                PropVariantInit(&pv);
                // Get the next Object to delete
                hr = pObjectIDs->GetAt(dwIndex, &pv);
                CHECK_HR(hr, "Failed to get next object id at index %d", dwIndex);
                if (hr == S_OK)
                {
                    HRESULT     hrDelete = S_OK;
                    PROPVARIANT pvResult = {0};

                    PropVariantInit(&pvResult);

                    hrDelete = m_pDevice->DeleteObject(Scope, dwOptions, pv.pwszVal, pEventParams);
                    CHECK_HR(hrDelete, "Failed to delete object [%ws]", pv.pwszVal);

                    if(FAILED(hrDelete))
                    {
                        bDeleteFailed = TRUE;
                    }
                    else
                    {
                        // Delete is successful, so we post an event.  
                        // This is best effort, so errors are ignored
                        HRESULT hrEvent = PostWpdEvent(pParams, pEventParams);  
                        CHECK_HR(hrEvent, "Failed post event for deleted object [%ws] (errors ignored)", pv.pwszVal);
                    }

                    // Clear event parameters for reuse
                    pEventParams->Clear();

                    // Save this result
                    pvResult.vt       = VT_ERROR;
                    pvResult.scode    = hrDelete;
                    hrTemp = pDeleteResults->Add(&pvResult);
                    PropVariantClear(&pvResult);
                    CHECK_HR(hrTemp, "Failed to add result for [%ws] to list of results", pv.pwszVal);

                    PropVariantClear(&pv);
                }
                else
                {
                    break;
                }
            }
        }
    }

    // Set the results
    if (hr == S_OK)
    {
        hr = pResults->SetIPortableDevicePropVariantCollectionValue(WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS, pDeleteResults);
        CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_MANAGEMENT_DELETE_RESULTS");
    }

    // If an object failed to delete, make sure we return S_FALSE
    if ((hr == S_OK) && (bDeleteFailed))
    {
        hr = S_FALSE;
    }

    return hr;
}