locked
How can I use IFileSyncProviderCallback in unmanaged code (C++) RRS feed

  • Question

  • I have created a dialog application in C++, which should synchronize files between folders.

    I use the Sync Framework 2.0. I have created tow instances of IFileSyncProvider. The synchronization with this configuration works fine. But if I want to use the IFileSyncProviderCallback, i got an access violation, during starting (ISyncSession::Start) the synchronization. Before I got the access violation the event handler "OnChangeApplied" of my coclass is called.

    Here is my synchronization code:

    HRESULT CSyncDlg::Synchronize(const GUID* pguidReplicaSrc, CString* pstrFolderSrc,
                                          CString* pstrMetaSrc, const GUID* pguidReplicaDest, CString* pstrFolderDest, CString* pstrMetaDest)
    {
      HRESULT hr = E_UNEXPECTED;

      hr = CoInitialize(NULL);

      if(SUCCEEDED(hr))
      {
        // Create the source and destination providers.
        IFileSyncProvider* pProvSrc = NULL;

        hr = CoCreateInstance(CLSID_FileSyncProvider, NULL, CLSCTX_INPROC_SERVER, __uuidof(pProvSrc), (void**)&pProvSrc);

        if(SUCCEEDED(hr))
        {
          IFileSyncProvider* pProvDest = NULL;

          hr = CoCreateInstance(CLSID_FileSyncProvider, NULL, CLSCTX_INPROC_SERVER, __uuidof(pProvDest), (void**)&pProvDest);

          if(SUCCEEDED(hr))
          {
            // Create a file sync provider callback
            CComPtr<IFileSyncProviderCallback> pCallback;
           
            hr = CoCreateInstance(IID_IFileSyncProviderCallback, NULL, CLSCTX_INPROC_SERVER, __uuidof(pCallback), (void**)&pCallback);

            // Create a scope filter and fill it (some strings may be empty).
            IFileSyncScopeFilter* pFilter = NULL;

            hr = pProvSrc->CreateNewScopeFilter(&pFilter);

            if (SUCCEEDED(hr))
            {
              //hr = pFilter->SetFilenameExcludes(LPCWSTR("File.ID"));

              if(SUCCEEDED(hr))
              {
                //hr = pFilter->SetSubDirectoryExcludes(m_strDirExc.GetString());
              }

              if(SUCCEEDED(hr))
              {
                //DWORD dwMask = wcstoul(m_strAttrExc.GetString(), NULL, 16);
                //hr = pFilter->SetFileAttributeExcludeMask(dwMask);
              }

              if(SUCCEEDED(hr))
              {
                // Only set the include list if we have something in it, because
                // setting the include list to empty effectively excludes all files.
                if (!m_strFilenameInc.IsEmpty())
                {
                  hr = pFilter->SetFilenameIncludes(LPCWSTR("*"));
                }
              }

              if(SUCCEEDED(hr))
              {

                // Initialize the providers.
                hr = pProvSrc->Initialize(*pguidReplicaSrc, CA2W(pstrFolderSrc->GetString()),
                    CA2W(pstrMetaSrc->GetString()), NULL,
                    FILESYNC_INIT_FLAGS_NONE, pFilter, NULL, NULL);

                if(SUCCEEDED(hr))
                {
                  hr = pProvDest->Initialize(*pguidReplicaDest, CA2W(pstrFolderDest->GetString()),
                      CA2W(pstrMetaDest->GetString()), NULL,
                      FILESYNC_INIT_FLAGS_NONE, pFilter, pCallback, NULL);
                }
              }

              pFilter->Release();
            }

            if (SUCCEEDED(hr))
            {
              // Synchronize!
              IApplicationSyncServices* pSvc = NULL;
              hr = CoCreateInstance(CLSID_SyncServices, NULL, CLSCTX_INPROC_SERVER,
                  IID_IApplicationSyncServices, (void**)&pSvc);

              if(SUCCEEDED(hr))
              {
                ISyncSession* pSession = NULL;
                hr = pSvc->CreateSyncSession(pProvDest, pProvSrc, &pSession);

                if (SUCCEEDED(hr))
                {
                  SYNC_SESSION_STATISTICS syncStats;
                  hr = pSession->Start(CRP_NONE, &syncStats); // !!! HERE: ACCESS VIOLATION !!!

                  pSession->Release();
                }

                pSvc->Release();
              }
            }

            pProvDest->Release();
          }
      
          pProvSrc->Release();
        }

        CoUninitialize();
      }

      return hr;
    }

     

    And here the coclass of IFileSyncProviderCallback:

    class ATL_NO_VTABLE CFileSyncProviderCallback :
        public CComObjectRootEx<CComSingleThreadModel>,
        public CComCoClass<CFileSyncProviderCallback, &IID_IFileSyncProviderCallback>
    {
    public:
        CFileSyncProviderCallback()
        {
        }

    DECLARE_REGISTRY_RESOURCEID(IDR_FILESYNCPROVIDERCALLBACK)


    BEGIN_COM_MAP(CFileSyncProviderCallback)
        COM_INTERFACE_ENTRY_IID(IID_IFileSyncProviderCallback, CFileSyncProviderCallback)
    END_COM_MAP()


        DECLARE_PROTECT_FINAL_CONSTRUCT()

        HRESULT FinalConstruct()
        {
            return S_OK;
        }

        void FinalRelease()
        {
        }

    public:
      STDMETHOD(OnChangeApplied)(LPCWSTR pcszNewFilePath, LPCWSTR pcszOldFilePath, DWORD dwChangeType);
      STDMETHOD(OnChangeDetectionProgress)(LPCWSTR pcszDirectoryPath);
      STDMETHOD(OnDetectFileSkipped)(LPCWSTR pcszSourceFilePath, DWORD dwReason, HRESULT hrErrorCode);
      STDMETHOD(OnChangeDetectionCompleted)(LONGLONG llTotalFilesFound, LONGLONG llTotalDirectoriesFound, LONGLONG llTotalFileSize);
      STDMETHOD(OnApplyingChange)(LPCWSTR pcszNewDirectoryPath, LPCWSTR pcszCurrentDirectoryPath, const WIN32_FIND_DATAW *pNewFileInfo, const WIN32_FIND_DATAW *pCurrentFileInfo, DWORD dwChangeType, BOOL *pfSkipChange);
      STDMETHOD(OnFileCopyProgress)(LPCWSTR pcszNewFilePath, DWORD dwPercentCopied);
      STDMETHOD(OnChangeSkipped)(LPCWSTR pcszNewFilePath, LPCWSTR pcszCurrentFilePath, DWORD dwChangeType, DWORD dwReason, HRESULT hrErrorCode);
    };

    OBJECT_ENTRY_AUTO(IID_IFileSyncProviderCallback, CFileSyncProviderCallback)

    Tuesday, July 27, 2010 7:48 AM

All replies

  • Hello,

    For detecting access violation, I would recommend using Debugging Tools for Windows a.k.a WinDbg.

    I looked at the code, and attching the callback itself and passing it to provider initialize method seems correct.

    Access violation is likely to be at event handling implementation.

    32 bit version of Windbg is available here: http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx#b 

    Patrick

    Wednesday, July 28, 2010 10:11 PM
  • Hello,

     

    Trying the same thing:

     hr = CoCreateInstance(IID_IFileSyncProviderCallback, NULL, CLSCTX_INPROC_SERVER, __uuidof(pCallback), (void**)&pCallback);

    throws: object not present... (have added the object in ATL..)

     

    Did you ever got this fixed?

     

    Best regards:

     

    Rimmer van den Bogert


    Ribo
    Wednesday, November 16, 2011 12:04 AM