Leaked source code of windows server 2003
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

  1. // MdSync.hxx: Definition of the MdSync class
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_MDSYNC_H__C97912DF_997E_11D0_A5F6_00A0C922E752__INCLUDED_)
  5. #define AFX_MDSYNC_H__C97912DF_997E_11D0_A5F6_00A0C922E752__INCLUDED_
  6. #if _MSC_VER >= 1001
  7. #pragma once
  8. #endif // _MSC_VER >= 1001
  9. #include "resource.h" // main symbols
  10. #include <nsepname.hxx>
  11. #include <iadm.h>
  12. #include <iiscnfgp.h>
  13. #include <replseed.hxx>
  14. #define TIMEOUT_VALUE 10000
  15. #define THREAD_COUNT 10
  16. #define RANDOM_SEED_SIZE 16 //size of random bits used to generate session key, in bytes
  17. #define SEED_MD_DATA_SIZE (RANDOM_SEED_SIZE + SEED_HEADER_SIZE)
  18. typedef enum {
  19. SCANMODE_QUIT,
  20. SCANMODE_SYNC_PROPS,
  21. SCANMODE_SYNC_OBJECTS
  22. } SCANMODE;
  23. class CMdIf
  24. {
  25. public:
  26. CMdIf() { m_pcAdmCom = NULL; m_hmd = NULL; m_fModified = FALSE; }
  27. ~CMdIf() { Terminate(); }
  28. BOOL Init( LPSTR pszComputer );
  29. BOOL Open( LPWSTR pszOpen = L"", DWORD dwAttr = METADATA_PERMISSION_READ );
  30. BOOL Close();
  31. BOOL Save()
  32. {
  33. m_pcAdmCom->SaveData();
  34. return TRUE;
  35. }
  36. BOOL Terminate();
  37. VOID SetModified()
  38. {
  39. m_fModified = TRUE;
  40. }
  41. BOOL Enum( LPWSTR pszPath, DWORD i, LPWSTR pName )
  42. {
  43. HRESULT hRes;
  44. hRes = m_pcAdmCom->EnumKeys( m_hmd, pszPath, pName, i );
  45. if ( FAILED( hRes ) )
  46. {
  47. SetLastError( HRESULTTOWIN32(hRes) );
  48. return FALSE;
  49. }
  50. return TRUE;
  51. }
  52. BOOL GetAllData( LPWSTR pszPath, LPDWORD pdwRec, LPDWORD pdwDataSet, LPBYTE pBuff, DWORD cBuff, LPDWORD pdwRequired )
  53. {
  54. HRESULT hRes;
  55. hRes = m_pcAdmCom->GetAllData( m_hmd,
  56. pszPath,
  57. 0,
  58. ALL_METADATA,
  59. ALL_METADATA,
  60. pdwRec,
  61. pdwDataSet,
  62. cBuff,
  63. pBuff,
  64. pdwRequired );
  65. if ( FAILED( hRes ) )
  66. {
  67. SetLastError( HRESULTTOWIN32(hRes) );
  68. return FALSE;
  69. }
  70. return TRUE;
  71. }
  72. BOOL GetData( LPWSTR pszPath, PMETADATA_RECORD pmd, LPVOID pData, LPDWORD pdwRequired )
  73. {
  74. METADATA_RECORD md = *pmd;
  75. HRESULT hRes;
  76. md.pbMDData = (LPBYTE)pData;
  77. hRes = m_pcAdmCom->GetData( m_hmd, pszPath, &md, pdwRequired );
  78. if ( FAILED( hRes ) )
  79. {
  80. SetLastError( HRESULTTOWIN32(hRes) );
  81. return FALSE;
  82. }
  83. return TRUE;
  84. }
  85. BOOL SetData( LPWSTR pszPath, PMETADATA_RECORD pmd, LPVOID pData )
  86. {
  87. METADATA_RECORD md = *pmd;
  88. HRESULT hRes;
  89. md.pbMDData = (LPBYTE)pData;
  90. hRes = m_pcAdmCom->SetData( m_hmd, pszPath, &md );
  91. if ( FAILED( hRes ) )
  92. {
  93. SetLastError( HRESULTTOWIN32(hRes) );
  94. return FALSE;
  95. }
  96. return TRUE;
  97. }
  98. BOOL DeleteProp( LPWSTR pszPath, PMETADATA_RECORD pmd )
  99. {
  100. HRESULT hRes;
  101. hRes = m_pcAdmCom->DeleteData( m_hmd, pszPath, pmd->dwMDIdentifier, pmd->dwMDDataType );
  102. if ( FAILED( hRes ) )
  103. {
  104. SetLastError( HRESULTTOWIN32(hRes) );
  105. return FALSE;
  106. }
  107. return TRUE;
  108. }
  109. BOOL DeleteSubTree( LPWSTR pszPath )
  110. {
  111. HRESULT hRes;
  112. hRes = m_pcAdmCom->DeleteChildKeys( m_hmd, pszPath );
  113. hRes = m_pcAdmCom->DeleteKey( m_hmd, pszPath );
  114. if ( FAILED( hRes ) )
  115. {
  116. SetLastError( HRESULTTOWIN32(hRes) );
  117. return FALSE;
  118. }
  119. return TRUE;
  120. }
  121. BOOL AddNode( LPWSTR pszPath )
  122. {
  123. HRESULT hRes;
  124. hRes = m_pcAdmCom->AddKey( m_hmd, pszPath );
  125. if ( FAILED( hRes ) )
  126. {
  127. SetLastError( HRESULTTOWIN32(hRes) );
  128. return FALSE;
  129. }
  130. return TRUE;
  131. }
  132. BOOL GetLastChangeTime( LPWSTR pszPath, PFILETIME pftMDLastChangeTime )
  133. {
  134. HRESULT hRes;
  135. hRes = m_pcAdmCom->GetLastChangeTime( m_hmd, pszPath, pftMDLastChangeTime, FALSE );
  136. if ( FAILED( hRes ) )
  137. {
  138. SetLastError( HRESULTTOWIN32(hRes) );
  139. return FALSE;
  140. }
  141. return TRUE;
  142. }
  143. BOOL SetLastChangeTime( LPWSTR pszPath, PFILETIME pftMDLastChangeTime )
  144. {
  145. HRESULT hRes;
  146. hRes = m_pcAdmCom->SetLastChangeTime( m_hmd, pszPath, pftMDLastChangeTime, FALSE );
  147. if ( FAILED( hRes ) )
  148. {
  149. SetLastError( HRESULTTOWIN32(hRes) );
  150. return FALSE;
  151. }
  152. return TRUE;
  153. }
  154. private:
  155. IMSAdminBaseW * m_pcAdmCom; //interface pointer
  156. METADATA_HANDLE m_hmd;
  157. BOOL m_fModified;
  158. } ;
  159. #if defined(ADMEX)
  160. class CRpIf
  161. {
  162. public:
  163. CRpIf() { m_pcAdmCom = NULL; }
  164. ~CRpIf() { Terminate(); }
  165. BOOL Init( LPSTR pszComputer, CLSID* pClsid );
  166. BOOL Terminate();
  167. BOOL GetSignature( BUFFER* pbuf, LPDWORD pdwBufSize )
  168. {
  169. DWORD dwRequired;
  170. HRESULT hRes;
  171. hRes = m_pcAdmCom->GetSignature( pbuf->QuerySize(),
  172. (LPBYTE)pbuf->QueryPtr(),
  173. &dwRequired );
  174. if ( hRes == RETURNCODETOHRESULT( ERROR_INSUFFICIENT_BUFFER ) )
  175. {
  176. if ( !pbuf->Resize( dwRequired ) )
  177. {
  178. return FALSE;
  179. }
  180. hRes = m_pcAdmCom->GetSignature( pbuf->QuerySize(),
  181. (LPBYTE)pbuf->QueryPtr(),
  182. &dwRequired );
  183. }
  184. if ( FAILED( hRes ) )
  185. {
  186. SetLastError( HRESULTTOWIN32(hRes) );
  187. return FALSE;
  188. }
  189. else
  190. {
  191. *pdwBufSize = dwRequired;
  192. }
  193. return TRUE;
  194. }
  195. BOOL Serialize( BUFFER* pbuf, LPDWORD pdwBufSize )
  196. {
  197. DWORD dwRequired;
  198. HRESULT hRes;
  199. hRes = m_pcAdmCom->Serialize( pbuf->QuerySize(),
  200. (LPBYTE)pbuf->QueryPtr(),
  201. &dwRequired );
  202. if ( hRes == RETURNCODETOHRESULT( ERROR_INSUFFICIENT_BUFFER ) )
  203. {
  204. if ( !pbuf->Resize( dwRequired ) )
  205. {
  206. return FALSE;
  207. }
  208. hRes = m_pcAdmCom->Serialize( pbuf->QuerySize(),
  209. (LPBYTE)pbuf->QueryPtr(),
  210. &dwRequired );
  211. }
  212. if ( FAILED( hRes ) )
  213. {
  214. SetLastError( HRESULTTOWIN32(hRes) );
  215. return FALSE;
  216. }
  217. else
  218. {
  219. *pdwBufSize = dwRequired;
  220. }
  221. return TRUE;
  222. }
  223. BOOL DeSerialize( BUFFER* pbuf, DWORD cBuff )
  224. {
  225. HRESULT hRes;
  226. hRes = m_pcAdmCom->DeSerialize( cBuff,
  227. (LPBYTE)pbuf->QueryPtr() );
  228. if ( FAILED( hRes ) )
  229. {
  230. SetLastError( HRESULTTOWIN32(hRes) );
  231. return FALSE;
  232. }
  233. return TRUE;
  234. }
  235. BOOL Propagate( char* pTarget, DWORD cTarget )
  236. {
  237. HRESULT hRes;
  238. hRes = m_pcAdmCom->Propagate( cTarget,
  239. (LPBYTE)pTarget );
  240. if ( FAILED( hRes ) )
  241. {
  242. SetLastError( HRESULTTOWIN32(hRes) );
  243. return FALSE;
  244. }
  245. return TRUE;
  246. }
  247. BOOL Propagate2( char* pTarget, DWORD cTarget, DWORD dwF )
  248. {
  249. HRESULT hRes;
  250. hRes = m_pcAdmCom->Propagate2( cTarget,
  251. (LPBYTE)pTarget,
  252. dwF );
  253. if ( FAILED( hRes ) )
  254. {
  255. SetLastError( HRESULTTOWIN32(hRes) );
  256. return FALSE;
  257. }
  258. return TRUE;
  259. }
  260. private:
  261. IMSAdminReplication* m_pcAdmCom; //interface pointer
  262. } ;
  263. #endif
  264. class CTargetBitmask
  265. {
  266. public:
  267. CTargetBitmask() { m_pbTargets = NULL; m_dwTargets = 0; }
  268. ~CTargetBitmask() { if ( m_pbTargets ) LocalFree( m_pbTargets ); }
  269. BOOL Init( DWORD dwNbTargets, BOOL fSt = TRUE )
  270. {
  271. if ( m_pbTargets )
  272. {
  273. LocalFree( m_pbTargets );
  274. }
  275. if ( m_pbTargets = (LPBYTE)LocalAlloc( LMEM_FIXED, dwNbTargets ) )
  276. {
  277. memset( m_pbTargets, fSt , dwNbTargets );
  278. m_dwTargets = dwNbTargets;
  279. return TRUE;
  280. }
  281. return FALSE;
  282. }
  283. DWORD FindUntouchedTarget()
  284. {
  285. DWORD dwT;
  286. for ( dwT = 0 ; dwT < m_dwTargets ; ++dwT )
  287. {
  288. if ( m_pbTargets[dwT] )
  289. {
  290. m_pbTargets[dwT] = 0x0;
  291. return dwT;
  292. }
  293. }
  294. return 0xffffffff;
  295. }
  296. BOOL GetFlag( DWORD dwI )
  297. {
  298. return m_pbTargets[dwI];
  299. }
  300. VOID SetFlag( DWORD dwI, DWORD dwV )
  301. {
  302. m_pbTargets[dwI] = (BYTE)dwV;
  303. }
  304. private:
  305. LPBYTE m_pbTargets;
  306. DWORD m_dwTargets;
  307. } ;
  308. typedef struct _THREAD_CONTEXT
  309. {
  310. PVOID pvContext;
  311. DWORD dwIndex;
  312. HANDLE hSemaphore;
  313. } THREAD_CONTEXT, *PTHREAD_CONTEXT;
  314. template <class T>
  315. class CTargetStatus
  316. {
  317. public:
  318. CTargetStatus() { m_pTargets = NULL; m_dwTargets = 0; }
  319. ~CTargetStatus() { if ( m_pTargets ) LocalFree( m_pTargets ); }
  320. BOOL Init( DWORD dwNbTargets )
  321. {
  322. if ( m_pTargets )
  323. {
  324. LocalFree( m_pTargets );
  325. }
  326. if ( m_pTargets = (T*)LocalAlloc( LMEM_FIXED,
  327. dwNbTargets * sizeof(T)) )
  328. {
  329. memset( m_pTargets, '\x0' , dwNbTargets * sizeof(T) );
  330. m_dwTargets = dwNbTargets;
  331. return TRUE;
  332. }
  333. return FALSE;
  334. }
  335. T GetStatus( DWORD dwI ) { return m_pTargets[dwI]; }
  336. VOID SetStatus( DWORD dwI, T value ) { m_pTargets[dwI] = value; };
  337. T* GetPtr( DWORD dwI ) { return m_pTargets+dwI; }
  338. BOOL IsError()
  339. {
  340. for ( UINT i = 0 ; i < m_dwTargets ; ++i )
  341. {
  342. if ( m_pTargets[i] )
  343. {
  344. return TRUE;
  345. }
  346. }
  347. return FALSE;
  348. }
  349. private:
  350. T* m_pTargets;
  351. DWORD m_dwTargets;
  352. };
  353. class CNodeDesc;
  354. #define AER_PHASE1 1
  355. #define AER_PHASE2 2
  356. class CSync
  357. {
  358. public:
  359. CSync();
  360. ~CSync();
  361. VOID Lock() { EnterCriticalSection( &m_csLock ); }
  362. VOID Unlock() { LeaveCriticalSection( &m_csLock ); }
  363. HRESULT Sync( LPSTR pwszTargets, LPDWORD pdwResults, DWORD dwFlags, SYNC_STAT* pStat );
  364. BOOL GenerateKeySeed();
  365. BOOL PropagateKeySeed();
  366. BOOL DeleteKeySeed();
  367. HRESULT Cancel()
  368. {
  369. UINT i;
  370. m_fCancel = TRUE;
  371. if ( m_fInScan )
  372. {
  373. for ( i = 0 ; i < m_dwThreads ; ++i )
  374. {
  375. SignalWorkItem( i );
  376. }
  377. }
  378. return S_OK;
  379. }
  380. BOOL ScanTarget( DWORD dwTarget );
  381. VOID SignalWorkItem( DWORD dwI )
  382. {
  383. ReleaseSemaphore( m_ThreadContext.GetPtr(dwI)->hSemaphore, 1, NULL );
  384. }
  385. VOID WaitForWorkItem( DWORD dwI )
  386. {
  387. WaitForSingleObject( m_ThreadContext.GetPtr(dwI)->hSemaphore, INFINITE );
  388. }
  389. DWORD GetTargetCount()
  390. {
  391. return m_dwTargets;
  392. }
  393. VOID SetTargetError( DWORD dwTarget, DWORD dwError );
  394. DWORD GetTargetError(DWORD dwTarget )
  395. {
  396. return m_TargetStatus.GetStatus( dwTarget );
  397. }
  398. BOOL IsLocal( DWORD dwTarget )
  399. {
  400. return !m_bmIsRemote.GetFlag( dwTarget );
  401. }
  402. BOOL IsCancelled()
  403. {
  404. return m_fCancel;
  405. }
  406. BOOL
  407. GetProp(
  408. LPWSTR pszPath,
  409. DWORD dwPropId,
  410. DWORD dwUserType,
  411. DWORD dwDataType,
  412. LPBYTE* ppBuf,
  413. LPDWORD pdwLen
  414. );
  415. VOID IncrementSourceScan() { ++m_pStat->m_dwSourceScan; }
  416. VOID IncrementTargetScan( DWORD dwTarget ) { ++m_pStat->m_adwTargets[dwTarget*2]; }
  417. VOID IncrementTargetTouched( DWORD dwTarget ) { ++m_pStat->m_adwTargets[dwTarget*2+1]; }
  418. VOID SetSourceComplete() { m_pStat->m_fSourceComplete = TRUE; }
  419. DWORD QueryFlags() { return m_dwFlags;}
  420. CMdIf* GetSourceIf() { return &m_Source; }
  421. CMdIf* GetTargetIf( DWORD i ) { return m_pTargets[i]; }
  422. BOOL ScanThread();
  423. BOOL ProcessQueuedRequest();
  424. BOOL ProcessAdminExReplication( LPWSTR, LPSTR, DWORD );
  425. BOOL QueueRequest( DWORD dwId, LPWSTR pszPath, DWORD dwTarget, FILETIME* );
  426. VOID SetModified( DWORD i ) { m_pTargets[i]->SetModified(); }
  427. VOID SetTargetSignatureMismatch( DWORD i, DWORD iC, BOOL fSt)
  428. { m_bmTargetSignatureMismatch.SetFlag( i + iC*m_dwTargets, fSt ); }
  429. DWORD GetTargetSignatureMismatch( DWORD i, DWORD iC )
  430. { return (DWORD)m_bmTargetSignatureMismatch.GetFlag(i + iC*m_dwTargets); }
  431. LIST_ENTRY m_QueuedRequestsHead;
  432. LONG m_lThreads;
  433. private:
  434. CNodeDesc* m_pRoot;
  435. CMdIf** m_pTargets;
  436. DWORD m_dwTargets;
  437. CMdIf m_Source;
  438. CTargetStatus<DWORD> m_TargetStatus;
  439. CTargetStatus<HANDLE> m_ThreadHandle;
  440. CTargetStatus<THREAD_CONTEXT> m_ThreadContext;
  441. BOOL m_fCancel;
  442. DWORD m_dwThreads;
  443. CTargetBitmask m_bmIsRemote;
  444. CTargetBitmask m_bmTargetSignatureMismatch;
  445. CRITICAL_SECTION m_csQueuedRequestsList;
  446. CRITICAL_SECTION m_csLock;
  447. BOOL m_fInScan;
  448. DWORD m_dwFlags;
  449. SYNC_STAT* m_pStat;
  450. BYTE m_rgbSeed[SEED_MD_DATA_SIZE];
  451. DWORD m_cbSeed;
  452. } ;
  453. class CNseRequest {
  454. public:
  455. CNseRequest::CNseRequest();
  456. CNseRequest::~CNseRequest();
  457. BOOL Match( LPWSTR pszPath, DWORD dwId )
  458. {
  459. return !_wcsicmp( pszPath, m_pszPath ) && dwId == m_dwId;
  460. }
  461. BOOL Init( LPWSTR pszPath, LPWSTR pszCreatePath, LPWSTR pszCreateObject, DWORD dwId, DWORD dwTargetCount, LPWSTR pszModifPath, FILETIME*, METADATA_RECORD* );
  462. VOID AddTarget( DWORD i ) { m_bmTarget.SetFlag( i, TRUE ); }
  463. BOOL Process( CSync* );
  464. LIST_ENTRY m_QueuedRequestsList;
  465. private:
  466. LPWSTR m_pszPath;
  467. LPWSTR m_pszCreatePath;
  468. LPWSTR m_pszCreateObject;
  469. LPWSTR m_pszModifPath;
  470. DWORD m_dwId;
  471. DWORD m_dwTargetCount;
  472. CTargetBitmask m_bmTarget;
  473. LPBYTE m_pbData;
  474. DWORD m_dwData;
  475. FILETIME m_ftModif;
  476. METADATA_RECORD m_md;
  477. } ;
  478. class CProps
  479. {
  480. public:
  481. CProps();
  482. ~CProps();
  483. BOOL GetAll( CMdIf*, LPWSTR );
  484. VOID SetRefCount( DWORD dwRefCount )
  485. {
  486. m_lRefCount = (LONG)dwRefCount;
  487. }
  488. VOID Dereference()
  489. {
  490. if ( !InterlockedDecrement( &m_lRefCount ) )
  491. {
  492. if ( m_Props )
  493. {
  494. LocalFree( m_Props );
  495. m_Props = NULL;
  496. }
  497. }
  498. }
  499. BOOL IsNse( DWORD dwId )
  500. {
  501. return dwId == MD_SERIAL_CERT11 ||
  502. dwId == MD_SERIAL_DIGEST;
  503. }
  504. BOOL NseIsDifferent( DWORD dwId, LPBYTE pSourceData, DWORD dwSourceLen, LPBYTE pTargetData, DWORD dwTargetLen, LPWSTR pszPath, DWORD dwTarget );
  505. BOOL NseSet( DWORD dwId, CSync*, LPWSTR pszPath, DWORD dwTarget );
  506. LPBYTE GetProps() { return m_Props; }
  507. DWORD GetPropsCount() { return m_dwProps; }
  508. private:
  509. LPBYTE m_Props;
  510. DWORD m_dwProps;
  511. DWORD m_dwLenProps;
  512. LONG m_lRefCount;
  513. } ;
  514. class CNodeDesc
  515. {
  516. public:
  517. CNodeDesc( CSync* );
  518. ~CNodeDesc();
  519. BOOL Scan( CSync* pSync );
  520. BOOL ScanTarget( DWORD dwTarget );
  521. BOOL SetPath( LPWSTR pszPath )
  522. {
  523. if ( m_pszPath )
  524. {
  525. LocalFree( m_pszPath );
  526. }
  527. if ( !(m_pszPath = (LPWSTR)LocalAlloc( LMEM_FIXED, (wcslen(pszPath)+1)*sizeof(WCHAR) )) )
  528. {
  529. return FALSE;
  530. }
  531. wcscpy( m_pszPath, pszPath );
  532. return TRUE;
  533. }
  534. LPWSTR GetPath() { return m_pszPath; }
  535. BOOL DoWork( SCANMODE sm, DWORD dwtarget );
  536. BOOL BuildChildObjectsList( CMdIf*, LPWSTR pszPath );
  537. // list of child CNodeDesc
  538. LIST_ENTRY m_ChildHead; // to CNodeDesc
  539. LIST_ENTRY m_ChildList;
  540. private:
  541. // source properties
  542. CProps m_Props;
  543. CTargetBitmask m_bmProps;
  544. CTargetBitmask m_bmObjs;
  545. BOOL m_fHasProps;
  546. BOOL m_fHasObjs;
  547. //
  548. LPWSTR m_pszPath;
  549. CSync* m_pSync;
  550. } ;
  551. /////////////////////////////////////////////////////////////////////////////
  552. // MdSync
  553. class MdSync :
  554. public IMdSync,
  555. public CComObjectRoot,
  556. public CComCoClass<MdSync,&CLSID_MdSync>
  557. {
  558. public:
  559. MdSync() {}
  560. BEGIN_COM_MAP(MdSync)
  561. COM_INTERFACE_ENTRY(IMdSync)
  562. END_COM_MAP()
  563. //DECLARE_NOT_AGGREGATABLE(MdSync)
  564. // Remove the comment from the line above if you don't want your object to
  565. // support aggregation.
  566. DECLARE_REGISTRY_RESOURCEID(IDR_MdSync)
  567. // IMdSync
  568. public:
  569. STDMETHOD(Synchronize)( LPSTR mszTargets, LPDWORD pdwResults, DWORD dwFlags, LPDWORD pdwStat );
  570. STDMETHOD(Cancel) ();
  571. private:
  572. CSync m_Sync;
  573. };
  574. #endif // !defined(AFX_MDSYNC_H__C97912DF_997E_11D0_A5F6_00A0C922E752__INCLUDED_)
  575.