895 lines
32 KiB
C++
895 lines
32 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// Module Name:
|
|
// MyDeviceSyncItem.cpp
|
|
//
|
|
// Abstract:
|
|
// Implementation of the Sync Center sync item for a device.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Pch.h"
|
|
#include "MyDeviceSyncItem.h"
|
|
#include "MyDeviceSyncHandler.h"
|
|
#include "BrowseUI.h"
|
|
#include "Guids.h" // Declare the GUIDs used by this component.
|
|
#include "Helpers.h"
|
|
#include "Resources.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// class CMyDeviceSyncItem
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Create an instance of the sync item class.
|
|
//
|
|
// Parameters:
|
|
// pszItemID - ID of the item.
|
|
// pszItemName - Name of the item.
|
|
// pszItemLabel - Label of the item.
|
|
// pszHandlerID - ID of the handler creating the item
|
|
// folderID - KNOWNFOLDERID of the folder which the item represents
|
|
// uSyncTextID - String to be displayed during item syncronization
|
|
// ppSyncItem - Sync item object being returned.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
// E_OUTOFMEMORY - Error allocating the object.
|
|
// Other HRESULTs - Error querying for requested interface.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT CMyDeviceSyncItem_CreateInstance(
|
|
__in LPCWSTR pszItemID,
|
|
__in LPCWSTR pszItemName,
|
|
__in LPCWSTR pszItemLabel,
|
|
__in LPCWSTR pszHandlerID,
|
|
__in KNOWNFOLDERID folderID,
|
|
__in UINT uSyncTextID,
|
|
__deref_out CMyDeviceSyncItem **ppSyncItem)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
*ppSyncItem = new CMyDeviceSyncItem(pszItemID, pszItemName, pszItemLabel, pszHandlerID, folderID, uSyncTextID);
|
|
if (*ppSyncItem == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
hr = (*ppSyncItem)->RegisterIconLocation();
|
|
}
|
|
|
|
return hr;
|
|
|
|
} //*** CMyDeviceSyncItem_CreateInstance
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Constructor.
|
|
//
|
|
// Parameters:
|
|
// pszItemID - ID of the item.
|
|
// pszItemName - Name of the item.
|
|
// pszItemLabel - Label of the item.
|
|
// pszHandlerID - ID of the handler creating the item.
|
|
// folderID - KNOWNFOLDERID of the folder which the item represents.
|
|
// uSyncTextID - String to be displayed during item syncronization.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CMyDeviceSyncItem::CMyDeviceSyncItem(
|
|
__in LPCWSTR pszItemID,
|
|
__in LPCWSTR pszItemName,
|
|
__in LPCWSTR pszItemLabel,
|
|
__in LPCWSTR pszHandlerID,
|
|
__in KNOWNFOLDERID folderID,
|
|
__in UINT uSyncTextID)
|
|
:
|
|
_cRef(1),
|
|
_folderID(folderID),
|
|
_uSyncTextID(uSyncTextID)
|
|
{
|
|
DllAddRef();
|
|
|
|
// Truncation should NEVER happen.
|
|
assert(lstrlenW(pszItemID) < ARRAYSIZE(_szItemID));
|
|
StringCchCopyW(_szItemID, ARRAYSIZE(_szItemID), pszItemID);
|
|
assert(lstrlenW(pszHandlerID) < ARRAYSIZE(_szHandlerID));
|
|
StringCchCopyW(_szHandlerID, ARRAYSIZE(_szHandlerID), pszHandlerID);
|
|
|
|
// Truncation is okay.
|
|
StringCchCopyW(_szItemName, ARRAYSIZE(_szItemName), pszItemName);
|
|
StringCchCopyW(_szItemLabel, ARRAYSIZE(_szItemLabel), pszItemLabel);
|
|
|
|
} //*** constructor CMyDeviceSyncItem::CMyDeviceSyncItem
|
|
|
|
//----------------------------------------------------------------------------
|
|
// IUnknown (CMyDeviceSyncItem)
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP CMyDeviceSyncItem::QueryInterface(__in REFIID riid, __deref_out void **ppv)
|
|
{
|
|
static const QITAB qit[] =
|
|
{
|
|
QITABENT(CMyDeviceSyncItem, ISyncMgrSyncItem),
|
|
QITABENT(CMyDeviceSyncItem, ISyncMgrSyncItemInfo),
|
|
{ 0 },
|
|
};
|
|
|
|
return QISearch(this, qit, riid, ppv);
|
|
|
|
} //*** CMyDeviceSyncSyncItem::QueryInterface
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP_(ULONG) CMyDeviceSyncItem::Release()
|
|
{
|
|
ULONG cRef = InterlockedDecrement(&_cRef);
|
|
if (cRef == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
return cRef;
|
|
|
|
} //*** CMyDeviceSyncItem::Release
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ISyncMgrSyncItem (CMyDeviceSyncItem)
|
|
//----------------------------------------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to get the ID of the Item.
|
|
//
|
|
// Implements: ISyncMgrSyncItem
|
|
//
|
|
// Parameters:
|
|
// ppszItemID - ID of item being returned.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
// Other HRESULTs.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::GetItemID(__deref_out LPWSTR *ppszItemID)
|
|
{
|
|
// Duplicate the item ID string for the caller.
|
|
HRESULT hr = SHStrDupW(_szItemID, ppszItemID);
|
|
|
|
return hr;
|
|
|
|
} //*** CMyDeviceSyncItem::GetItemID
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to get the name of the item. This name will be
|
|
// displayed in the handler's folder.
|
|
//
|
|
// Parameters:
|
|
// ppszName - Name of the item being returned.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
// Other HRESULTs.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::GetName(__deref_out LPWSTR *ppszName)
|
|
{
|
|
*ppszName = NULL;
|
|
|
|
// Duplicate the name for the caller.
|
|
HRESULT hr = SHStrDupW(_szItemName, ppszName);
|
|
|
|
return hr;
|
|
|
|
} //*** CMyDeviceSyncItem::GetName
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to get information about the sync item.
|
|
//
|
|
// Implements: ISyncMgrSyncItem
|
|
//
|
|
// Parameters:
|
|
// ppItemInfo - Interface for getting sync item info to return to Sync Center.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
// Other HRESULTs.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::GetItemInfo(__deref_out ISyncMgrSyncItemInfo **ppItemInfo)
|
|
{
|
|
HRESULT hr = QueryInterface(IID_PPV_ARGS(ppItemInfo));
|
|
return hr;
|
|
|
|
} //*** CMyDeviceSyncItem::GetItemInfo
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to get an interface pointer for a specific
|
|
// type of object.
|
|
//
|
|
// Implements: ISyncMgrSyncItem
|
|
//
|
|
// Parameters:
|
|
// rguidObjectID - GUID for the item to get the object for.
|
|
// riid - Interface to get.
|
|
// ppv - Interface returned to Sync Center.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
// E_NOTIMPL - Not implemented by the sync item.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::GetObject(
|
|
__in REFGUID rguidObjectID,
|
|
__in REFIID riid,
|
|
__deref_out void **ppv)
|
|
{
|
|
HRESULT hr = E_NOTIMPL;
|
|
*ppv = NULL;
|
|
|
|
if (rguidObjectID == SYNCMGR_OBJECTID_BrowseContent)
|
|
{
|
|
hr = CBrowseUI_CreateInstance(_folderID, riid, ppv);
|
|
}
|
|
|
|
return hr;
|
|
|
|
} //*** CMyDeviceSyncItem::GetObject
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to get the mask of capabilities of the item.
|
|
// The following capabilities are defined:
|
|
//
|
|
// SYNCMGR_ICM_NONE
|
|
// No capabilities are specified.
|
|
//
|
|
// SYNCMGR_ICM_PROVIDES_ICON
|
|
// Indicates that the item will return a valid object from the
|
|
// GetObject() method when SYNCMGR_OBJECTID_Icon is specified.
|
|
//
|
|
// SYNCMGR_ICM_EVENT_STORE
|
|
// Indicates that the item will return a valid object from the
|
|
// GetObject() method when SYNCMGR_OBJECTID_EventStore is specified.
|
|
//
|
|
// SYNCMGR_ICM_CONFLICT_STORE
|
|
// Indicates that the item will return a valid object from the
|
|
// GetObject() method when SYNCMGR_OBJECTID_ConflictStore is
|
|
// specified.
|
|
//
|
|
// SYNCMGR_ICM_CAN_DELETE
|
|
// Indicates that the item wants to allow the user to be able to
|
|
// delete it from the handler's folder. This can be used by an item
|
|
// to remove that item from the handler's sync set (e.g. remove
|
|
// a folder from the set of Offline Files).
|
|
//
|
|
// If this value is set the Delete task will be shown in the
|
|
// handler's folder when this item is selected.
|
|
//
|
|
// SYNCMGR_ICM_BROWSE_CONTENT
|
|
// Indicates that the item will return a valid object from the
|
|
// GetObject() method when SYNCMGR_OBJECTID_BrowseContent is
|
|
// specified. If this value is set, the Browse Content task will be
|
|
// added to the context menu for the item.
|
|
//
|
|
// SYNCMGR_ICM_QUERY_BEFORE_ENABLE
|
|
// Indicates that the item will return a valid object from the
|
|
// GetObject() method when SYNCMGR_OBJECTID_QueryBeforeEnable is
|
|
// specified.
|
|
//
|
|
// SYNCMGR_ICM_QUERY_BEFORE_DISABLE
|
|
// Indicates that the item will return a valid object from the
|
|
// GetObject() method when SYNCMGR_OBJECTID_QueryBeforeDisable is
|
|
// specified.
|
|
//
|
|
// SYNCMGR_ICM_QUERY_BEFORE_DELETE
|
|
// Indicates that the item will return a valid object from the
|
|
// GetObject() method when SYNCMGR_OBJECTID_QueryBeforeDelete is
|
|
// specified.
|
|
//
|
|
// Implements: ISyncMgrSyncItem
|
|
//
|
|
// Parameters:
|
|
// pmCapabilities - Capabilities mask being returned.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::GetCapabilities(__out SYNCMGR_ITEM_CAPABILITIES *pmCapabilities)
|
|
{
|
|
*pmCapabilities = SYNCMGR_ICM_CAN_BROWSE_CONTENT;
|
|
return S_OK;
|
|
|
|
} //*** CMyDeviceSyncItem::GetCapabilities
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to get the mask of policies of the item.
|
|
// The following policies are defined:
|
|
//
|
|
// SYNCMGR_IPM_NONE
|
|
// No policies are specified.
|
|
//
|
|
// SYNCMGR_IPM_PREVENT_ENABLE
|
|
// Indicates that enabling the item is not supported. This can be
|
|
// used by an item to implement support for group policy that
|
|
// prevents an item from being enabled. If this value is set the
|
|
// Enable task will not be shown in the handler's folder when this
|
|
// item is selected. The item should provide a comment (returned
|
|
// from its implement of the GetComment() method on
|
|
// ISyncMgrSyncItemInfo) to let the user know why the Enable task is
|
|
// not available. Most items should never set this value.
|
|
//
|
|
// SYNCMGR_IC_PREVENT_DISABLE
|
|
// Indicates that disabling the item is not supported. This can be
|
|
// used by an item to implement support for group policy that forces
|
|
// an item to always be able to sync. If this value is set the
|
|
// Disable task will not be shown in the handler's folder when this
|
|
// item is selected. The item should provide a comment (returned
|
|
// from its implementation of the GetComment() method on
|
|
// ISyncMgrSyncItemInfo) to let the user know why the Disable task is
|
|
// not available. Most items should never set this value.
|
|
//
|
|
// SYNCMGR_IPM_PREVENT_START_SYNC
|
|
// Indicates that starting a sync through the user interface or
|
|
// through the APIs is not supported. Sync can only be started by
|
|
// an external application that creates a session creator to report
|
|
// progress. If this value is set, the Start Sync task will not be
|
|
// shown in the handler's folder when the sync item is selected.
|
|
// Note that Start Sync must be supported on a handler in order for
|
|
// it to be supported on a sync item. Most sync items should not set
|
|
// this value.
|
|
//
|
|
// SYNCMGR_IPM_PREVENT_STOP_SYNC
|
|
// Indicates that stopping a sync through the user interface or
|
|
// through the APIs is not supported. If this value is set, the
|
|
// Stop Sync task will not be shown in the handler's folder when the
|
|
// sync item is selected. Note that Stop Sync must be supported on a
|
|
// handler in order for it to be supported on a sync item. Most sync
|
|
// items should not set this value.
|
|
//
|
|
// SYNCMGR_IPM_DISABLE_ENABLE
|
|
// Indicates that the enable task should be disabled when it is
|
|
// shown for this sync item. With this policy set, the Enable option
|
|
// will appear in the context menu (if SYNCMGR_IPM_PREVENT_ENABLE is
|
|
// not set) but will be disabled.
|
|
//
|
|
// SYNCMGR_IPM_DISABLE_DISABLE
|
|
// Indicates that the disable task should be disabled when it is
|
|
// shown for this sync item. With this policy set, the Disable option
|
|
// will appear in the context menu (if SYNCMGR_IPM_PREVENT_DISABLE is
|
|
// not set) but will be disabled.
|
|
//
|
|
// SYNCMGR_IPM_DISABLE_START_SYNC
|
|
// Indicates that the Start Sync task should be disabled when it is
|
|
// shown for this sync item. With this policy set, the Start Sync
|
|
// option will appear in the context menu (if
|
|
// SYNCMGR_IPM_PREVENT_START_SYNC is not set and if
|
|
// SYNCMGR_HPM_PREVENT_START_SYNC is not set on the handler) but will
|
|
// be disabled.
|
|
//
|
|
// SYNCMGR_IPM_DISABLE_STOP_SYNC
|
|
// Indicates that the Stop Sync task should be disabled when it is
|
|
// shown for this sync item. With this policy set, the Stop Sync
|
|
// option will appear in the context menu (if
|
|
// SYNCMGR_IPM_PREVENT_STOP_SYNC is not set and if
|
|
// SYNCMGR_HPM_PREVENT_STOP_SYNC is not set on the handler) but will
|
|
// be disabled.
|
|
//
|
|
// SYNCMGR_IPM_DISABLE_BROWSE
|
|
// Indicates that the Browse task should be disabled when it is shown
|
|
// for this sync item. The Browse task will only be shown if the
|
|
// SYNCMGR_ICM_CAN_BROWSE_CONTENT value is returned from the
|
|
// GetCapabilities() method.
|
|
//
|
|
// SYNCMGR_IPM_HIDDEN_BY_DEFAULT
|
|
// Indicates that the item should be hidden from the user unless
|
|
// the Show Hidden Files option has been enabled. This policy only
|
|
// applies the first time the item is loaded. After that, the hidden
|
|
// state is maintained by Sync Center and can be changed by the user
|
|
// through the property sheet.
|
|
//
|
|
// Implements: ISyncMgrSyncItem
|
|
//
|
|
// Parameters:
|
|
// pmPolicies - Policy mask being returned.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::GetPolicies(__out SYNCMGR_ITEM_POLICIES *pmPolicies)
|
|
{
|
|
*pmPolicies = SYNCMGR_IPM_NONE;
|
|
return S_OK;
|
|
|
|
} //*** CMyDeviceSyncItem::GetPolicies
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center when the user chooses to enable or disable the
|
|
// sync item from the handler's folder.
|
|
//
|
|
// Implements: ISyncMgrSyncItem
|
|
//
|
|
// Return Values:
|
|
// S_OK - Sync item changed enabled state successfully.
|
|
// Failure HRESULTs - Sync item failed to change the enabled state.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::Enable(BOOL fEnable)
|
|
{
|
|
UNREFERENCED_PARAMETER(fEnable);
|
|
return S_OK;
|
|
|
|
} //*** CMyDeviceSyncItem::Enable
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center when the user chooses to delete the sync item
|
|
// from the handler's folder.
|
|
//
|
|
// Implements: ISyncMgrSyncItem
|
|
//
|
|
// Return Values:
|
|
// S_OK - Sync item was deleted successfully.
|
|
// Failure HRESULT - Sync item failed to delete the sync item.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::Delete()
|
|
{
|
|
return E_NOTIMPL;
|
|
|
|
} //*** CMyDeviceSyncItem::Delete
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ISyncMgrSyncItemInfo (CMyDeviceSyncItem)
|
|
//----------------------------------------------------------------------------
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to get a label for the item type. This is
|
|
// usually used to display the model of the device or some other item-
|
|
// specific identifying string.
|
|
//
|
|
// Implements: ISyncMgrSyncItemInfo
|
|
//
|
|
// Parameters:
|
|
// ppszLabel
|
|
// Pointer to fill with a pointer to a string. Must be allocated
|
|
// with CoTaskMemAlloc(). Sync Center will free this using
|
|
// CoTaskMemFree().
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
// E_OUTOFMEMORY - Error allocating memory for the string buffer.
|
|
// Other HRESULTs.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::GetTypeLabel(__deref_out LPWSTR *ppszLabel)
|
|
{
|
|
*ppszLabel = NULL;
|
|
|
|
// Duplicate the name for the caller.
|
|
HRESULT hr = SHStrDupW(_szItemLabel, ppszLabel);
|
|
|
|
return hr;
|
|
|
|
} //*** CMyDeviceSyncItem::GetTypeLabel
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to get a string to display in the folder in
|
|
// the far right column when a synchronization is not being performed.
|
|
// If no string is provided, a blank string will be displayed.
|
|
//
|
|
// Parameters:
|
|
// ppszComment
|
|
// Pointer to fill with a pointer to a string. Must be allocated
|
|
// with CoTaskMemAlloc(). Sync Center will free this using
|
|
// CoTaskMemFree().
|
|
//
|
|
// Implements: ISyncMgrSyncItemInfo
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
// E_OUTOFMEMORY - Error allocating memory for the string buffer.
|
|
// E_NOTIMPL - No comment is provided by the handler.
|
|
// Other HRESULTs.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::GetComment(__deref_out LPWSTR *ppszComment)
|
|
{
|
|
*ppszComment = NULL;
|
|
return E_NOTIMPL;
|
|
|
|
} //*** CMyDeviceSyncItem::GetComment
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to get the date and time the item was last
|
|
// synchronized. If a failure is returned, the value calculated from the
|
|
// last synchronization will be used.
|
|
//
|
|
// Implements: ISyncMgrSyncItemInfo
|
|
//
|
|
// Parameters:
|
|
// pftLastSync - Last sync time.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Operation completed successfully.
|
|
// E_NOTIMPL - No last sync time is provided by the handler.
|
|
// Other HRESULTs.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::GetLastSyncTime(__out FILETIME *pftLastSync)
|
|
{
|
|
UNREFERENCED_PARAMETER(pftLastSync);
|
|
return E_NOTIMPL;
|
|
|
|
} //*** CMyDeviceSyncItem::GetLastSyncTime
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to determine whether the sync item is enabled
|
|
// or not.
|
|
//
|
|
// If a sync item is disabled it will not be synchronized by Sync Center
|
|
// and many of the actions will be removed or disabled in the UI.
|
|
//
|
|
// If a sync item doesn't want to maintain its enabled state, it can
|
|
// return E_NOTIMPL and Sync Center will maintain it for the sync item.
|
|
//
|
|
// Implements: ISyncMgrSyncItemInfo
|
|
//
|
|
// Return Values:
|
|
// S_OK - Sync item is enabled.
|
|
// S_FALSE - Sync item is not enabled.
|
|
// E_NOTIMPL - Let Sync Center maintain the enabled state.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::IsEnabled()
|
|
{
|
|
return E_NOTIMPL;
|
|
|
|
} //*** CMyDeviceSyncItem::IsEnabled
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called by Sync Center to determine whether the sync item is in a
|
|
// connected state or not.
|
|
//
|
|
// If an item is in a disconnected state it will not be synchronized by
|
|
// Sync Center and many of the actions will be removed or disabled in
|
|
// the UI.
|
|
//
|
|
// Implements: ISyncMgrSyncItemInfo
|
|
//
|
|
// Return Values:
|
|
// S_OK - Item is connected.
|
|
// S_FALSE - Item is disconnected.
|
|
// E_NOTIMPL - Item doesn't support this state.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
STDMETHODIMP CMyDeviceSyncItem::IsConnected()
|
|
{
|
|
return E_NOTIMPL;
|
|
|
|
} //*** CMyDeviceSyncItem::IsConnected
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Called at sync item creation to register the item's icon in the Windows
|
|
// registry. If this fails, Sync Center will use the GetObject() method
|
|
// to query for its icon.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Icon was successfully registered.
|
|
// Other HRESULTs - Icon registration failed.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT CMyDeviceSyncItem::RegisterIconLocation()
|
|
{
|
|
HKEY hkey;
|
|
HRESULT hr = _OpenIconLocationRegKey(&hkey);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// First check if the value on the DefaultIcon key exists.
|
|
// If it does, check the type and length. If it is a
|
|
// string value and is not empty we consider it a valid
|
|
// icon location. Otherwise, we will attempt to write
|
|
// the icon path there.
|
|
|
|
// MAX_PATH+12 to make room for the resource
|
|
// number that is stored after the path
|
|
WCHAR szIconLocation[MAX_PATH+12] = { 0 };
|
|
|
|
hr = _QueryIconLocationRegValue(hkey, szIconLocation, ARRAYSIZE(szIconLocation));
|
|
if (FAILED(hr))
|
|
{
|
|
// Icon location not yet registered or we found invalid data.
|
|
// [Re]register the icon location.
|
|
hr = _GetIconLocation(szIconLocation, ARRAYSIZE(szIconLocation));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = _WriteIconLocationRegValue(hkey, szIconLocation);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
return hr;
|
|
|
|
}//*** CMyDeviceSyncItem::RegisterIconLocation
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Binds to the shell item underlying the item's known folder and calls
|
|
// GetUIObjectOf. This is used to get an IExtractIconW interface for the
|
|
// sync item's known folder.
|
|
//
|
|
// Parameters:
|
|
// riid - IID of the interface to be passed to GetUIObjectOf.
|
|
// ppv - Pointer to the interface to be returned.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Pointer was successfully found.
|
|
// Other HRESULTs - Pointer was not found.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT CMyDeviceSyncItem::GetShellItemObject(__in REFIID riid, __out void **ppv)
|
|
{
|
|
LPWSTR pszPath = NULL;
|
|
|
|
HRESULT hr = SHGetKnownFolderPath(
|
|
_folderID,
|
|
0, /* dwFlags */
|
|
NULL, /* hToken */
|
|
&pszPath);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
PIDLIST_ABSOLUTE pidlFull;
|
|
ULONG ulAttr = 0;
|
|
hr = SHILCreateFromPath(pszPath, &pidlFull, &ulAttr);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Bind to the shell item's parent and then call GetUIObjectOf
|
|
IShellFolder *psf;
|
|
PCIDLIST_RELATIVE pidlItem;
|
|
hr = ::SHBindToFolderIDListParent(NULL, pidlFull, IID_PPV_ARGS(&psf), &pidlItem);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = psf->GetUIObjectOf(NULL, 1, &pidlItem, riid, NULL, ppv);
|
|
psf->Release();
|
|
}
|
|
|
|
ILFree(pidlFull);
|
|
}
|
|
|
|
CoTaskMemFree(pszPath);
|
|
}
|
|
|
|
return hr;
|
|
|
|
}//*** CMyDeviceSyncItem::GetShellItemObject
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Opens the registry key used by Sync Center for registering sync item
|
|
// icons with read/write privileges . If the key does not
|
|
// exist, it is created.
|
|
//
|
|
// Parameters:
|
|
// phkey - Open registry key to be returned.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Key was successfully opened.
|
|
// Other HRESULTs - Key was not opened.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT CMyDeviceSyncItem::_OpenIconLocationRegKey(__out HKEY *phkey)
|
|
{
|
|
*phkey = NULL;
|
|
|
|
LPWSTR pszKey = NULL;
|
|
HRESULT hr = FormatString(L"Software\\Microsoft\\Windows\\CurrentVersion\\SyncMgr\\HandlerInstances\\%1\\SyncItems\\%2\\DefaultIcon",
|
|
&pszKey,
|
|
_szHandlerID,
|
|
_szItemID);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD nStatus = RegCreateKeyExW(HKEY_CURRENT_USER,
|
|
pszKey,
|
|
0,
|
|
NULL,
|
|
0,
|
|
(KEY_WRITE | KEY_READ),
|
|
NULL,
|
|
phkey,
|
|
NULL);
|
|
|
|
if (nStatus != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(nStatus);
|
|
}
|
|
|
|
LocalFree(pszKey);
|
|
}
|
|
|
|
return hr;
|
|
|
|
}//*** CMyDeviceSyncItem::_OpenIconLocationRegKey
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Querys the value of the specified registry key. This is used to
|
|
// check the value of the key containing the path to the icon. If
|
|
// the value is not a string, or if it is empty, the value is certainly
|
|
// invalid and the method fails.
|
|
//
|
|
// Parameters:
|
|
// hkey - The open registry key to be queried.
|
|
// pszLocation - The buffer which will be filled with the value of the registry key.
|
|
// cchLocation - The size of the buffer pointed to by pszLocation, in characters.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Value was successfully queried.
|
|
// ERROR_INVALID_DATA - Registry key contains invalid data
|
|
// ERROR_NOT_FOUND - Registry key contains no data
|
|
// Other HRESULTs - The value queried was invalid.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT CMyDeviceSyncItem::_QueryIconLocationRegValue(
|
|
__in HKEY hkey,
|
|
__out_ecount(cchLocation) LPWSTR pszLocation,
|
|
__in size_t cchLocation)
|
|
{
|
|
DWORD dwType;
|
|
DWORD cbIconLocation = (DWORD)(cchLocation * sizeof(WCHAR));
|
|
DWORD dwResult = RegQueryValueExW(hkey,
|
|
NULL,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)pszLocation,
|
|
&cbIconLocation);
|
|
|
|
if (dwResult == ERROR_SUCCESS)
|
|
{
|
|
if (!(REG_SZ == dwType || REG_EXPAND_SZ == dwType))
|
|
{
|
|
// If the value is not a string type we want to write a new value.
|
|
dwResult = ERROR_INVALID_DATA;
|
|
}
|
|
else if (pszLocation[0] == L'\0')
|
|
{
|
|
// If the value is empty we want to write a new value.
|
|
dwResult = ERROR_NOT_FOUND;
|
|
}
|
|
|
|
// Ensure the output string is null-terminated.
|
|
pszLocation[cchLocation - 1] = 0;
|
|
}
|
|
|
|
return HRESULT_FROM_WIN32(dwResult);
|
|
|
|
}//*** CMyDeviceSyncItem::_QueryIconLocationRegValue
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Retrieves the path to the file which contains the icon used in
|
|
// Explorer to represent the folder which this Item synchronizes
|
|
// (My Music, My Documents, etc).
|
|
//
|
|
// Parameters:
|
|
// pszLocation - Buffer to be filled with the path to the file which holds the icon.
|
|
// cchLocation - Size of the buffer pointed to by pszLocation, in characters.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Path to icon was found.
|
|
// Other HRESULTs - Path to icon was not found.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT CMyDeviceSyncItem::_GetIconLocation(
|
|
__out_ecount(cchLocation) LPWSTR pszLocation,
|
|
__in size_t cchLocation
|
|
)
|
|
{
|
|
IExtractIconW *pei = NULL;
|
|
HRESULT hr = GetShellItemObject(IID_PPV_ARGS(&pei));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
int iIconIndex;
|
|
UINT uFlags;
|
|
hr = pei->GetIconLocation(GIL_FORSHELL, pszLocation, (UINT)cchLocation, &iIconIndex, &uFlags);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Format the string in the normal icon location syntax:
|
|
//
|
|
// c:\dir1\dir2\resfile.dll,<icon index>
|
|
//
|
|
// Note that the icon index normally comes back from the shell as
|
|
// a negative number indicating an icon resource ID, not an index.
|
|
// Our code here will automatically include that minus sign which
|
|
// is required when the number represents a resource ID.
|
|
hr = StringCchPrintfW(pszLocation, MAX_PATH+12, L"%s,%d", pszLocation, iIconIndex);
|
|
}
|
|
|
|
pei->Release();
|
|
}
|
|
|
|
return hr;
|
|
|
|
}//*** CMyDeviceSyncItem::_GetIconLocation
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Description:
|
|
// Used to write the path of the icon to the registry.
|
|
//
|
|
// Parameters:
|
|
// hkey - Key (opened with write privilges) to write the path to.
|
|
// pszLocation - String containing the path to the icon.
|
|
//
|
|
// Return Values:
|
|
// S_OK - Value was successfully written.
|
|
// Other HRESULTs - Value was not written.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT CMyDeviceSyncItem::_WriteIconLocationRegValue(__in HKEY hkey, __in LPCWSTR pszLocation)
|
|
{
|
|
// Write the icon location string. Include the nul-terminator in the
|
|
// size of the written buffer.
|
|
HRESULT hr = S_OK;
|
|
DWORD cbLocation = (lstrlenW(pszLocation) + 1) * sizeof(WCHAR);
|
|
DWORD dwResult = RegSetValueExW(hkey,
|
|
NULL,
|
|
0,
|
|
REG_EXPAND_SZ,
|
|
(const BYTE *)pszLocation,
|
|
cbLocation);
|
|
|
|
if (dwResult != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwResult);
|
|
}
|
|
|
|
return hr;
|
|
|
|
}//*** CMyDeviceSyncItem::_WriteIconLocationRegValue
|
|
|
|
|