You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
668 lines
18 KiB
668 lines
18 KiB
// MdSync.hxx: Definition of the MdSync class
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#if !defined(AFX_MDSYNC_H__C97912DF_997E_11D0_A5F6_00A0C922E752__INCLUDED_)
|
|
#define AFX_MDSYNC_H__C97912DF_997E_11D0_A5F6_00A0C922E752__INCLUDED_
|
|
|
|
#if _MSC_VER >= 1001
|
|
#pragma once
|
|
#endif // _MSC_VER >= 1001
|
|
|
|
#include "resource.h" // main symbols
|
|
|
|
#include <nsepname.hxx>
|
|
#include <iadm.h>
|
|
#include <iiscnfgp.h>
|
|
#include <replseed.hxx>
|
|
|
|
#define TIMEOUT_VALUE 10000
|
|
#define THREAD_COUNT 10
|
|
#define RANDOM_SEED_SIZE 16 //size of random bits used to generate session key, in bytes
|
|
#define SEED_MD_DATA_SIZE (RANDOM_SEED_SIZE + SEED_HEADER_SIZE)
|
|
|
|
typedef enum {
|
|
|
|
SCANMODE_QUIT,
|
|
SCANMODE_SYNC_PROPS,
|
|
SCANMODE_SYNC_OBJECTS
|
|
} SCANMODE;
|
|
|
|
|
|
class CMdIf
|
|
{
|
|
public:
|
|
CMdIf() { m_pcAdmCom = NULL; m_hmd = NULL; m_fModified = FALSE; }
|
|
~CMdIf() { Terminate(); }
|
|
BOOL Init( LPSTR pszComputer );
|
|
BOOL Open( LPWSTR pszOpen = L"", DWORD dwAttr = METADATA_PERMISSION_READ );
|
|
BOOL Close();
|
|
BOOL Save()
|
|
{
|
|
m_pcAdmCom->SaveData();
|
|
return TRUE;
|
|
}
|
|
BOOL Terminate();
|
|
VOID SetModified()
|
|
{
|
|
m_fModified = TRUE;
|
|
}
|
|
BOOL Enum( LPWSTR pszPath, DWORD i, LPWSTR pName )
|
|
{
|
|
HRESULT hRes;
|
|
hRes = m_pcAdmCom->EnumKeys( m_hmd, pszPath, pName, i );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
BOOL GetAllData( LPWSTR pszPath, LPDWORD pdwRec, LPDWORD pdwDataSet, LPBYTE pBuff, DWORD cBuff, LPDWORD pdwRequired )
|
|
{
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->GetAllData( m_hmd,
|
|
pszPath,
|
|
0,
|
|
ALL_METADATA,
|
|
ALL_METADATA,
|
|
pdwRec,
|
|
pdwDataSet,
|
|
cBuff,
|
|
pBuff,
|
|
pdwRequired );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
BOOL GetData( LPWSTR pszPath, PMETADATA_RECORD pmd, LPVOID pData, LPDWORD pdwRequired )
|
|
{
|
|
METADATA_RECORD md = *pmd;
|
|
HRESULT hRes;
|
|
|
|
md.pbMDData = (LPBYTE)pData;
|
|
hRes = m_pcAdmCom->GetData( m_hmd, pszPath, &md, pdwRequired );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
BOOL SetData( LPWSTR pszPath, PMETADATA_RECORD pmd, LPVOID pData )
|
|
{
|
|
METADATA_RECORD md = *pmd;
|
|
HRESULT hRes;
|
|
|
|
md.pbMDData = (LPBYTE)pData;
|
|
hRes = m_pcAdmCom->SetData( m_hmd, pszPath, &md );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
BOOL DeleteProp( LPWSTR pszPath, PMETADATA_RECORD pmd )
|
|
{
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->DeleteData( m_hmd, pszPath, pmd->dwMDIdentifier, pmd->dwMDDataType );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
BOOL DeleteSubTree( LPWSTR pszPath )
|
|
{
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->DeleteChildKeys( m_hmd, pszPath );
|
|
hRes = m_pcAdmCom->DeleteKey( m_hmd, pszPath );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
BOOL AddNode( LPWSTR pszPath )
|
|
{
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->AddKey( m_hmd, pszPath );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
BOOL GetLastChangeTime( LPWSTR pszPath, PFILETIME pftMDLastChangeTime )
|
|
{
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->GetLastChangeTime( m_hmd, pszPath, pftMDLastChangeTime, FALSE );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
BOOL SetLastChangeTime( LPWSTR pszPath, PFILETIME pftMDLastChangeTime )
|
|
{
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->SetLastChangeTime( m_hmd, pszPath, pftMDLastChangeTime, FALSE );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
private:
|
|
|
|
IMSAdminBaseW * m_pcAdmCom; //interface pointer
|
|
METADATA_HANDLE m_hmd;
|
|
BOOL m_fModified;
|
|
} ;
|
|
|
|
|
|
#if defined(ADMEX)
|
|
|
|
class CRpIf
|
|
{
|
|
public:
|
|
CRpIf() { m_pcAdmCom = NULL; }
|
|
~CRpIf() { Terminate(); }
|
|
BOOL Init( LPSTR pszComputer, CLSID* pClsid );
|
|
BOOL Terminate();
|
|
BOOL GetSignature( BUFFER* pbuf, LPDWORD pdwBufSize )
|
|
{
|
|
DWORD dwRequired;
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->GetSignature( pbuf->QuerySize(),
|
|
(LPBYTE)pbuf->QueryPtr(),
|
|
&dwRequired );
|
|
|
|
if ( hRes == RETURNCODETOHRESULT( ERROR_INSUFFICIENT_BUFFER ) )
|
|
{
|
|
if ( !pbuf->Resize( dwRequired ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
hRes = m_pcAdmCom->GetSignature( pbuf->QuerySize(),
|
|
(LPBYTE)pbuf->QueryPtr(),
|
|
&dwRequired );
|
|
}
|
|
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
*pdwBufSize = dwRequired;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
BOOL Serialize( BUFFER* pbuf, LPDWORD pdwBufSize )
|
|
{
|
|
DWORD dwRequired;
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->Serialize( pbuf->QuerySize(),
|
|
(LPBYTE)pbuf->QueryPtr(),
|
|
&dwRequired );
|
|
|
|
if ( hRes == RETURNCODETOHRESULT( ERROR_INSUFFICIENT_BUFFER ) )
|
|
{
|
|
if ( !pbuf->Resize( dwRequired ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
hRes = m_pcAdmCom->Serialize( pbuf->QuerySize(),
|
|
(LPBYTE)pbuf->QueryPtr(),
|
|
&dwRequired );
|
|
}
|
|
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
*pdwBufSize = dwRequired;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
BOOL DeSerialize( BUFFER* pbuf, DWORD cBuff )
|
|
{
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->DeSerialize( cBuff,
|
|
(LPBYTE)pbuf->QueryPtr() );
|
|
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
BOOL Propagate( char* pTarget, DWORD cTarget )
|
|
{
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->Propagate( cTarget,
|
|
(LPBYTE)pTarget );
|
|
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
BOOL Propagate2( char* pTarget, DWORD cTarget, DWORD dwF )
|
|
{
|
|
HRESULT hRes;
|
|
|
|
hRes = m_pcAdmCom->Propagate2( cTarget,
|
|
(LPBYTE)pTarget,
|
|
dwF );
|
|
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SetLastError( HRESULTTOWIN32(hRes) );
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
private:
|
|
|
|
IMSAdminReplication* m_pcAdmCom; //interface pointer
|
|
} ;
|
|
#endif
|
|
|
|
|
|
class CTargetBitmask
|
|
{
|
|
public:
|
|
CTargetBitmask() { m_pbTargets = NULL; m_dwTargets = 0; }
|
|
~CTargetBitmask() { if ( m_pbTargets ) LocalFree( m_pbTargets ); }
|
|
BOOL Init( DWORD dwNbTargets, BOOL fSt = TRUE )
|
|
{
|
|
if ( m_pbTargets )
|
|
{
|
|
LocalFree( m_pbTargets );
|
|
}
|
|
if ( m_pbTargets = (LPBYTE)LocalAlloc( LMEM_FIXED, dwNbTargets ) )
|
|
{
|
|
memset( m_pbTargets, fSt , dwNbTargets );
|
|
m_dwTargets = dwNbTargets;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
DWORD FindUntouchedTarget()
|
|
{
|
|
DWORD dwT;
|
|
for ( dwT = 0 ; dwT < m_dwTargets ; ++dwT )
|
|
{
|
|
if ( m_pbTargets[dwT] )
|
|
{
|
|
m_pbTargets[dwT] = 0x0;
|
|
return dwT;
|
|
}
|
|
}
|
|
return 0xffffffff;
|
|
}
|
|
BOOL GetFlag( DWORD dwI )
|
|
{
|
|
return m_pbTargets[dwI];
|
|
}
|
|
VOID SetFlag( DWORD dwI, DWORD dwV )
|
|
{
|
|
m_pbTargets[dwI] = (BYTE)dwV;
|
|
}
|
|
|
|
private:
|
|
LPBYTE m_pbTargets;
|
|
DWORD m_dwTargets;
|
|
} ;
|
|
|
|
typedef struct _THREAD_CONTEXT
|
|
{
|
|
PVOID pvContext;
|
|
DWORD dwIndex;
|
|
HANDLE hSemaphore;
|
|
} THREAD_CONTEXT, *PTHREAD_CONTEXT;
|
|
|
|
template <class T>
|
|
class CTargetStatus
|
|
{
|
|
public:
|
|
CTargetStatus() { m_pTargets = NULL; m_dwTargets = 0; }
|
|
~CTargetStatus() { if ( m_pTargets ) LocalFree( m_pTargets ); }
|
|
|
|
BOOL Init( DWORD dwNbTargets )
|
|
{
|
|
if ( m_pTargets )
|
|
{
|
|
LocalFree( m_pTargets );
|
|
}
|
|
|
|
if ( m_pTargets = (T*)LocalAlloc( LMEM_FIXED,
|
|
dwNbTargets * sizeof(T)) )
|
|
{
|
|
memset( m_pTargets, '\x0' , dwNbTargets * sizeof(T) );
|
|
m_dwTargets = dwNbTargets;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
T GetStatus( DWORD dwI ) { return m_pTargets[dwI]; }
|
|
VOID SetStatus( DWORD dwI, T value ) { m_pTargets[dwI] = value; };
|
|
T* GetPtr( DWORD dwI ) { return m_pTargets+dwI; }
|
|
|
|
BOOL IsError()
|
|
{
|
|
for ( UINT i = 0 ; i < m_dwTargets ; ++i )
|
|
{
|
|
if ( m_pTargets[i] )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
private:
|
|
T* m_pTargets;
|
|
DWORD m_dwTargets;
|
|
};
|
|
|
|
|
|
class CNodeDesc;
|
|
|
|
#define AER_PHASE1 1
|
|
#define AER_PHASE2 2
|
|
|
|
class CSync
|
|
{
|
|
public:
|
|
CSync();
|
|
~CSync();
|
|
|
|
VOID Lock() { EnterCriticalSection( &m_csLock ); }
|
|
VOID Unlock() { LeaveCriticalSection( &m_csLock ); }
|
|
|
|
HRESULT Sync( LPSTR pwszTargets, LPDWORD pdwResults, DWORD dwFlags, SYNC_STAT* pStat );
|
|
|
|
BOOL GenerateKeySeed();
|
|
|
|
BOOL PropagateKeySeed();
|
|
|
|
BOOL DeleteKeySeed();
|
|
|
|
HRESULT Cancel()
|
|
{
|
|
UINT i;
|
|
m_fCancel = TRUE;
|
|
if ( m_fInScan )
|
|
{
|
|
for ( i = 0 ; i < m_dwThreads ; ++i )
|
|
{
|
|
SignalWorkItem( i );
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
BOOL ScanTarget( DWORD dwTarget );
|
|
|
|
VOID SignalWorkItem( DWORD dwI )
|
|
{
|
|
ReleaseSemaphore( m_ThreadContext.GetPtr(dwI)->hSemaphore, 1, NULL );
|
|
}
|
|
VOID WaitForWorkItem( DWORD dwI )
|
|
{
|
|
WaitForSingleObject( m_ThreadContext.GetPtr(dwI)->hSemaphore, INFINITE );
|
|
}
|
|
|
|
DWORD GetTargetCount()
|
|
{
|
|
return m_dwTargets;
|
|
}
|
|
VOID SetTargetError( DWORD dwTarget, DWORD dwError );
|
|
DWORD GetTargetError(DWORD dwTarget )
|
|
{
|
|
return m_TargetStatus.GetStatus( dwTarget );
|
|
}
|
|
BOOL IsLocal( DWORD dwTarget )
|
|
{
|
|
return !m_bmIsRemote.GetFlag( dwTarget );
|
|
}
|
|
BOOL IsCancelled()
|
|
{
|
|
return m_fCancel;
|
|
}
|
|
|
|
BOOL
|
|
GetProp(
|
|
LPWSTR pszPath,
|
|
DWORD dwPropId,
|
|
DWORD dwUserType,
|
|
DWORD dwDataType,
|
|
LPBYTE* ppBuf,
|
|
LPDWORD pdwLen
|
|
);
|
|
|
|
VOID IncrementSourceScan() { ++m_pStat->m_dwSourceScan; }
|
|
VOID IncrementTargetScan( DWORD dwTarget ) { ++m_pStat->m_adwTargets[dwTarget*2]; }
|
|
VOID IncrementTargetTouched( DWORD dwTarget ) { ++m_pStat->m_adwTargets[dwTarget*2+1]; }
|
|
VOID SetSourceComplete() { m_pStat->m_fSourceComplete = TRUE; }
|
|
|
|
DWORD QueryFlags() { return m_dwFlags;}
|
|
CMdIf* GetSourceIf() { return &m_Source; }
|
|
CMdIf* GetTargetIf( DWORD i ) { return m_pTargets[i]; }
|
|
BOOL ScanThread();
|
|
BOOL ProcessQueuedRequest();
|
|
BOOL ProcessAdminExReplication( LPWSTR, LPSTR, DWORD );
|
|
BOOL QueueRequest( DWORD dwId, LPWSTR pszPath, DWORD dwTarget, FILETIME* );
|
|
VOID SetModified( DWORD i ) { m_pTargets[i]->SetModified(); }
|
|
|
|
VOID SetTargetSignatureMismatch( DWORD i, DWORD iC, BOOL fSt)
|
|
{ m_bmTargetSignatureMismatch.SetFlag( i + iC*m_dwTargets, fSt ); }
|
|
|
|
DWORD GetTargetSignatureMismatch( DWORD i, DWORD iC )
|
|
{ return (DWORD)m_bmTargetSignatureMismatch.GetFlag(i + iC*m_dwTargets); }
|
|
|
|
LIST_ENTRY m_QueuedRequestsHead;
|
|
LONG m_lThreads;
|
|
|
|
private:
|
|
CNodeDesc* m_pRoot;
|
|
CMdIf** m_pTargets;
|
|
DWORD m_dwTargets;
|
|
CMdIf m_Source;
|
|
CTargetStatus<DWORD> m_TargetStatus;
|
|
CTargetStatus<HANDLE> m_ThreadHandle;
|
|
CTargetStatus<THREAD_CONTEXT> m_ThreadContext;
|
|
BOOL m_fCancel;
|
|
DWORD m_dwThreads;
|
|
CTargetBitmask m_bmIsRemote;
|
|
CTargetBitmask m_bmTargetSignatureMismatch;
|
|
CRITICAL_SECTION m_csQueuedRequestsList;
|
|
CRITICAL_SECTION m_csLock;
|
|
BOOL m_fInScan;
|
|
DWORD m_dwFlags;
|
|
SYNC_STAT* m_pStat;
|
|
BYTE m_rgbSeed[SEED_MD_DATA_SIZE];
|
|
DWORD m_cbSeed;
|
|
} ;
|
|
|
|
|
|
class CNseRequest {
|
|
public:
|
|
CNseRequest::CNseRequest();
|
|
CNseRequest::~CNseRequest();
|
|
BOOL Match( LPWSTR pszPath, DWORD dwId )
|
|
{
|
|
return !_wcsicmp( pszPath, m_pszPath ) && dwId == m_dwId;
|
|
}
|
|
BOOL Init( LPWSTR pszPath, LPWSTR pszCreatePath, LPWSTR pszCreateObject, DWORD dwId, DWORD dwTargetCount, LPWSTR pszModifPath, FILETIME*, METADATA_RECORD* );
|
|
VOID AddTarget( DWORD i ) { m_bmTarget.SetFlag( i, TRUE ); }
|
|
BOOL Process( CSync* );
|
|
|
|
LIST_ENTRY m_QueuedRequestsList;
|
|
|
|
private:
|
|
LPWSTR m_pszPath;
|
|
LPWSTR m_pszCreatePath;
|
|
LPWSTR m_pszCreateObject;
|
|
LPWSTR m_pszModifPath;
|
|
DWORD m_dwId;
|
|
DWORD m_dwTargetCount;
|
|
CTargetBitmask m_bmTarget;
|
|
LPBYTE m_pbData;
|
|
DWORD m_dwData;
|
|
FILETIME m_ftModif;
|
|
METADATA_RECORD m_md;
|
|
} ;
|
|
|
|
|
|
class CProps
|
|
{
|
|
public:
|
|
CProps();
|
|
~CProps();
|
|
BOOL GetAll( CMdIf*, LPWSTR );
|
|
VOID SetRefCount( DWORD dwRefCount )
|
|
{
|
|
m_lRefCount = (LONG)dwRefCount;
|
|
}
|
|
VOID Dereference()
|
|
{
|
|
if ( !InterlockedDecrement( &m_lRefCount ) )
|
|
{
|
|
if ( m_Props )
|
|
{
|
|
LocalFree( m_Props );
|
|
m_Props = NULL;
|
|
}
|
|
}
|
|
}
|
|
BOOL IsNse( DWORD dwId )
|
|
{
|
|
return dwId == MD_SERIAL_CERT11 ||
|
|
dwId == MD_SERIAL_DIGEST;
|
|
}
|
|
BOOL NseIsDifferent( DWORD dwId, LPBYTE pSourceData, DWORD dwSourceLen, LPBYTE pTargetData, DWORD dwTargetLen, LPWSTR pszPath, DWORD dwTarget );
|
|
BOOL NseSet( DWORD dwId, CSync*, LPWSTR pszPath, DWORD dwTarget );
|
|
LPBYTE GetProps() { return m_Props; }
|
|
DWORD GetPropsCount() { return m_dwProps; }
|
|
|
|
private:
|
|
|
|
LPBYTE m_Props;
|
|
DWORD m_dwProps;
|
|
DWORD m_dwLenProps;
|
|
LONG m_lRefCount;
|
|
} ;
|
|
|
|
|
|
class CNodeDesc
|
|
{
|
|
public:
|
|
CNodeDesc( CSync* );
|
|
~CNodeDesc();
|
|
BOOL Scan( CSync* pSync );
|
|
BOOL ScanTarget( DWORD dwTarget );
|
|
BOOL SetPath( LPWSTR pszPath )
|
|
{
|
|
if ( m_pszPath )
|
|
{
|
|
LocalFree( m_pszPath );
|
|
}
|
|
if ( !(m_pszPath = (LPWSTR)LocalAlloc( LMEM_FIXED, (wcslen(pszPath)+1)*sizeof(WCHAR) )) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
wcscpy( m_pszPath, pszPath );
|
|
return TRUE;
|
|
}
|
|
LPWSTR GetPath() { return m_pszPath; }
|
|
BOOL DoWork( SCANMODE sm, DWORD dwtarget );
|
|
BOOL BuildChildObjectsList( CMdIf*, LPWSTR pszPath );
|
|
|
|
// list of child CNodeDesc
|
|
LIST_ENTRY m_ChildHead; // to CNodeDesc
|
|
LIST_ENTRY m_ChildList;
|
|
|
|
private:
|
|
// source properties
|
|
CProps m_Props;
|
|
CTargetBitmask m_bmProps;
|
|
CTargetBitmask m_bmObjs;
|
|
BOOL m_fHasProps;
|
|
BOOL m_fHasObjs;
|
|
//
|
|
LPWSTR m_pszPath;
|
|
CSync* m_pSync;
|
|
} ;
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// MdSync
|
|
|
|
class MdSync :
|
|
public IMdSync,
|
|
public CComObjectRoot,
|
|
public CComCoClass<MdSync,&CLSID_MdSync>
|
|
{
|
|
public:
|
|
MdSync() {}
|
|
BEGIN_COM_MAP(MdSync)
|
|
COM_INTERFACE_ENTRY(IMdSync)
|
|
END_COM_MAP()
|
|
//DECLARE_NOT_AGGREGATABLE(MdSync)
|
|
// Remove the comment from the line above if you don't want your object to
|
|
// support aggregation.
|
|
|
|
DECLARE_REGISTRY_RESOURCEID(IDR_MdSync)
|
|
|
|
// IMdSync
|
|
public:
|
|
STDMETHOD(Synchronize)( LPSTR mszTargets, LPDWORD pdwResults, DWORD dwFlags, LPDWORD pdwStat );
|
|
STDMETHOD(Cancel) ();
|
|
|
|
private:
|
|
CSync m_Sync;
|
|
};
|
|
|
|
#endif // !defined(AFX_MDSYNC_H__C97912DF_997E_11D0_A5F6_00A0C922E752__INCLUDED_)
|
|
|