|
|
// 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_)
|