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.

704 lines
17 KiB

  1. /*
  2. * irecinit.c - CReconcileInitiator implementation.
  3. */
  4. /* Headers
  5. **********/
  6. #include "project.h"
  7. #pragma hdrstop
  8. #include "oleutil.h"
  9. #include "irecinit.h"
  10. /* Types
  11. ********/
  12. /* ReconcileInitiator class */
  13. typedef struct _creconcileinitiator
  14. {
  15. /* IReconcileInitiator */
  16. IReconcileInitiator irecinit;
  17. /* IBriefcaseInitiator */
  18. IBriefcaseInitiator ibcinit;
  19. /* reference count */
  20. ULONG ulcRef;
  21. /* handle to parent briefcase */
  22. HBRFCASE hbr;
  23. /* status callback function */
  24. RECSTATUSPROC rsp;
  25. /* status callback function data */
  26. LPARAM lpCallbackData;
  27. /* IUnknown to release to abort reconciliation. */
  28. PIUnknown piunkForAbort;
  29. }
  30. CReconcileInitiator;
  31. DECLARE_STANDARD_TYPES(CReconcileInitiator);
  32. /* Module Prototypes
  33. ********************/
  34. PRIVATE_CODE HRESULT ReconcileInitiator_QueryInterface(PCReconcileInitiator, REFIID, PVOID *);
  35. PRIVATE_CODE ULONG ReconcileInitiator_AddRef(PCReconcileInitiator);
  36. PRIVATE_CODE ULONG ReconcileInitiator_Release(PCReconcileInitiator);
  37. PRIVATE_CODE HRESULT ReconcileInitiator_SetAbortCallback(PCReconcileInitiator, PIUnknown);
  38. PRIVATE_CODE HRESULT ReconcileInitiator_SetProgressFeedback(PCReconcileInitiator, ULONG, ULONG);
  39. PRIVATE_CODE HRESULT AbortReconciliation(PCReconcileInitiator);
  40. PRIVATE_CODE HRESULT RI_IReconcileInitiator_QueryInterface(PIReconcileInitiator, REFIID, PVOID *);
  41. PRIVATE_CODE ULONG RI_IReconcileInitiator_AddRef(PIReconcileInitiator);
  42. PRIVATE_CODE ULONG RI_IReconcileInitiator_Release(PIReconcileInitiator);
  43. PRIVATE_CODE HRESULT RI_IReconcileInitiator_SetAbortCallback(PIReconcileInitiator, PIUnknown);
  44. PRIVATE_CODE HRESULT RI_IReconcileInitiator_SetProgressFeedback( PIReconcileInitiator, ULONG, ULONG);
  45. PRIVATE_CODE HRESULT RI_IBriefcaseInitiator_QueryInterface(PIBriefcaseInitiator, REFIID, PVOID *);
  46. PRIVATE_CODE ULONG RI_IBriefcaseInitiator_AddRef(PIBriefcaseInitiator);
  47. PRIVATE_CODE ULONG RI_IBriefcaseInitiator_Release(PIBriefcaseInitiator);
  48. PRIVATE_CODE HRESULT RI_IBriefcaseInitiator_IsMonikerInBriefcase(PIBriefcaseInitiator, PIMoniker);
  49. #ifdef DEBUG
  50. PRIVATE_CODE BOOL IsValidPCCReconcileInitiator(PCCReconcileInitiator);
  51. PRIVATE_CODE BOOL IsValidPCIBriefcaseInitiator(PCIBriefcaseInitiator);
  52. #endif
  53. /* Module Variables
  54. *******************/
  55. /* IReconcileInitiator vtable */
  56. PRIVATE_DATA IReconcileInitiatorVtbl Mcirecinitvtbl =
  57. {
  58. &RI_IReconcileInitiator_QueryInterface,
  59. &RI_IReconcileInitiator_AddRef,
  60. &RI_IReconcileInitiator_Release,
  61. &RI_IReconcileInitiator_SetAbortCallback,
  62. &RI_IReconcileInitiator_SetProgressFeedback
  63. };
  64. /* IBriefcaseInitiator vtable */
  65. PRIVATE_DATA IBriefcaseInitiatorVtbl Mcibcinitvtbl =
  66. {
  67. &RI_IBriefcaseInitiator_QueryInterface,
  68. &RI_IBriefcaseInitiator_AddRef,
  69. &RI_IBriefcaseInitiator_Release,
  70. &RI_IBriefcaseInitiator_IsMonikerInBriefcase
  71. };
  72. /***************************** Private Functions *****************************/
  73. /*
  74. ** ReconcileInitiator_QueryInterface()
  75. **
  76. **
  77. **
  78. ** Arguments:
  79. **
  80. ** Returns:
  81. **
  82. ** Side Effects: none
  83. */
  84. PRIVATE_CODE HRESULT ReconcileInitiator_QueryInterface(
  85. PCReconcileInitiator precinit,
  86. REFIID riid, PVOID *ppvObject)
  87. {
  88. HRESULT hr;
  89. ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
  90. //ASSERT(IsValidREFIID(riid));
  91. ASSERT(IS_VALID_WRITE_PTR(ppvObject, PVOID));
  92. if (IsEqualIID(riid, &IID_IUnknown) ||
  93. IsEqualIID(riid, &IID_IReconcileInitiator))
  94. {
  95. *ppvObject = &(precinit->irecinit);
  96. precinit->irecinit.lpVtbl->AddRef(&(precinit->irecinit));
  97. hr = S_OK;
  98. }
  99. else if (IsEqualIID(riid, &IID_IBriefcaseInitiator))
  100. {
  101. *ppvObject = &(precinit->ibcinit);
  102. precinit->ibcinit.lpVtbl->AddRef(&(precinit->ibcinit));
  103. hr = S_OK;
  104. }
  105. else
  106. hr = E_NOINTERFACE;
  107. return(hr);
  108. }
  109. /*
  110. ** ReconcileInitiator_AddRef()
  111. **
  112. **
  113. **
  114. ** Arguments:
  115. **
  116. ** Returns:
  117. **
  118. ** Side Effects: none
  119. */
  120. PRIVATE_CODE ULONG ReconcileInitiator_AddRef(PCReconcileInitiator precinit)
  121. {
  122. ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
  123. ASSERT(precinit->ulcRef < ULONG_MAX);
  124. return(++(precinit->ulcRef));
  125. }
  126. /*
  127. ** ReconcileInitiator_Release()
  128. **
  129. **
  130. **
  131. ** Arguments:
  132. **
  133. ** Returns:
  134. **
  135. ** Side Effects: none
  136. */
  137. PRIVATE_CODE ULONG ReconcileInitiator_Release(PCReconcileInitiator precinit)
  138. {
  139. ULONG ulcRef;
  140. ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
  141. if (EVAL(precinit->ulcRef > 0))
  142. precinit->ulcRef--;
  143. ulcRef = precinit->ulcRef;
  144. if (! precinit->ulcRef)
  145. FreeMemory(precinit);
  146. return(ulcRef);
  147. }
  148. /*
  149. ** ReconcileInitiator_SetAbortCallback()
  150. **
  151. **
  152. **
  153. ** Arguments:
  154. **
  155. ** Returns:
  156. **
  157. ** Side Effects: none
  158. */
  159. PRIVATE_CODE HRESULT ReconcileInitiator_SetAbortCallback(
  160. PCReconcileInitiator precinit,
  161. PIUnknown piunkForAbort)
  162. {
  163. ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
  164. /* piunkForAbort can be legally NULL */
  165. ASSERT(NULL == piunkForAbort || IS_VALID_STRUCT_PTR(piunkForAbort, CIUnknown));
  166. precinit->piunkForAbort = piunkForAbort;
  167. return(S_OK);
  168. }
  169. /*
  170. ** ReconcileInitiator_SetProgressFeedback()
  171. **
  172. **
  173. **
  174. ** Arguments:
  175. **
  176. ** Returns:
  177. **
  178. ** Side Effects: none
  179. */
  180. PRIVATE_CODE HRESULT ReconcileInitiator_SetProgressFeedback(
  181. PCReconcileInitiator precinit,
  182. ULONG ulProgress,
  183. ULONG ulProgressMax)
  184. {
  185. RECSTATUSUPDATE rsu;
  186. /* ulProgress may be any value. */
  187. /* ulProgressMax may be any value. */
  188. ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
  189. rsu.ulScale = ulProgressMax;
  190. rsu.ulProgress = ulProgress;
  191. if (! NotifyReconciliationStatus(precinit->rsp, RS_DELTA_MERGE,
  192. (LPARAM)&rsu, precinit->lpCallbackData))
  193. AbortReconciliation(precinit);
  194. return(S_OK);
  195. }
  196. /*
  197. ** ReconcileInitiator_IsMonikerInBriefcase()
  198. **
  199. **
  200. **
  201. ** Arguments:
  202. **
  203. ** Returns:
  204. **
  205. ** Side Effects: none
  206. */
  207. PRIVATE_CODE HRESULT ReconcileInitiator_IsMonikerInBriefcase(
  208. PCReconcileInitiator precinit,
  209. PIMoniker pimk)
  210. {
  211. HRESULT hr;
  212. PIMoniker pimkBriefcase;
  213. ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
  214. ASSERT(IS_VALID_STRUCT_PTR(pimk, CIMoniker));
  215. hr = GetBriefcaseRootMoniker(precinit->hbr, &pimkBriefcase);
  216. if (SUCCEEDED(hr))
  217. {
  218. PIMoniker pimkCommonPrefix;
  219. hr = pimk->lpVtbl->CommonPrefixWith(pimk, pimkBriefcase,
  220. &pimkCommonPrefix);
  221. if (SUCCEEDED(hr))
  222. {
  223. switch (hr)
  224. {
  225. case MK_S_US:
  226. WARNING_OUT(((TEXT("ReconcileInitiator_IsMonikerInBriefcase(): Called on briefcase root."))));
  227. /* Fall through... */
  228. case MK_S_HIM:
  229. hr = S_OK;
  230. break;
  231. default:
  232. ASSERT(hr == S_OK ||
  233. hr == MK_S_ME);
  234. hr = S_FALSE;
  235. break;
  236. }
  237. #ifdef DEBUG
  238. {
  239. PIBindCtx pibindctx;
  240. BOOL bGotMoniker = FALSE;
  241. BOOL bGotBriefcase = FALSE;
  242. PWSTR pwszMoniker;
  243. PWSTR pwszBriefcase;
  244. PIMalloc pimalloc;
  245. if (SUCCEEDED(CreateBindCtx(0, &pibindctx)))
  246. {
  247. bGotMoniker = SUCCEEDED(pimk->lpVtbl->GetDisplayName(
  248. pimk, pibindctx,
  249. NULL,
  250. &pwszMoniker));
  251. bGotBriefcase = SUCCEEDED(pimkBriefcase->lpVtbl->GetDisplayName(
  252. pimkBriefcase,
  253. pibindctx, NULL,
  254. &pwszBriefcase));
  255. pibindctx->lpVtbl->Release(pibindctx);
  256. }
  257. if (! bGotMoniker)
  258. pwszMoniker = (PWSTR)L"UNAVAILABLE DISPLAY NAME";
  259. if (! bGotBriefcase)
  260. pwszBriefcase = (PWSTR)L"UNAVAILABLE DISPLAY NAME";
  261. TRACE_OUT(((TEXT("ReconcileInitiator_IsMonikerInBriefcase(): Moniker %ls is %s briefcase %ls.")),
  262. pwszMoniker,
  263. (hr == S_OK) ? "in" : "not in",
  264. pwszBriefcase));
  265. if (EVAL(GetIMalloc(&pimalloc)))
  266. {
  267. if (bGotMoniker)
  268. pimalloc->lpVtbl->Free(pimalloc, pwszMoniker);
  269. if (bGotBriefcase)
  270. pimalloc->lpVtbl->Free(pimalloc, pwszBriefcase);
  271. /* Do not release pimalloc. */
  272. }
  273. }
  274. #endif
  275. /* Do not release pimkBriefcase. */
  276. }
  277. }
  278. return(hr);
  279. }
  280. /*
  281. ** AbortReconciliation()
  282. **
  283. **
  284. **
  285. ** Arguments:
  286. **
  287. ** Returns:
  288. **
  289. ** Side Effects: none
  290. */
  291. PRIVATE_CODE HRESULT AbortReconciliation(PCReconcileInitiator precinit)
  292. {
  293. ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
  294. if (precinit->piunkForAbort)
  295. precinit->piunkForAbort->lpVtbl->Release(precinit->piunkForAbort);
  296. return(S_OK);
  297. }
  298. /*
  299. ** RI_IReconcileInitiator_QueryInterface()
  300. **
  301. **
  302. **
  303. ** Arguments:
  304. **
  305. ** Returns:
  306. **
  307. ** Side Effects: none
  308. */
  309. PRIVATE_CODE HRESULT RI_IReconcileInitiator_QueryInterface(
  310. PIReconcileInitiator pirecinit,
  311. REFIID riid, PVOID *ppvObject)
  312. {
  313. ASSERT(IS_VALID_STRUCT_PTR(pirecinit, CIReconcileInitiator));
  314. //ASSERT(IsValidREFIID(riid));
  315. ASSERT(IS_VALID_WRITE_PTR(ppvObject, PVOID));
  316. return(ReconcileInitiator_QueryInterface(
  317. ClassFromIface(CReconcileInitiator, irecinit, pirecinit),
  318. riid, ppvObject));
  319. }
  320. /*
  321. ** RI_IReconcileInitiator_AddRef()
  322. **
  323. **
  324. **
  325. ** Arguments:
  326. **
  327. ** Returns:
  328. **
  329. ** Side Effects: none
  330. */
  331. PRIVATE_CODE ULONG RI_IReconcileInitiator_AddRef(
  332. PIReconcileInitiator pirecinit)
  333. {
  334. ASSERT(IS_VALID_STRUCT_PTR(pirecinit, CIReconcileInitiator));
  335. return(ReconcileInitiator_AddRef(
  336. ClassFromIface(CReconcileInitiator, irecinit, pirecinit)));
  337. }
  338. /*
  339. ** RI_IReconcileInitiator_Release()
  340. **
  341. **
  342. **
  343. ** Arguments:
  344. **
  345. ** Returns:
  346. **
  347. ** Side Effects: none
  348. */
  349. PRIVATE_CODE ULONG RI_IReconcileInitiator_Release(
  350. PIReconcileInitiator pirecinit)
  351. {
  352. ASSERT(IS_VALID_STRUCT_PTR(pirecinit, CIReconcileInitiator));
  353. return(ReconcileInitiator_Release(
  354. ClassFromIface(CReconcileInitiator, irecinit, pirecinit)));
  355. }
  356. /*
  357. ** RI_IReconcileInitiator_SetAbortCallback()
  358. **
  359. **
  360. **
  361. ** Arguments:
  362. **
  363. ** Returns:
  364. **
  365. ** Side Effects: none
  366. */
  367. PRIVATE_CODE HRESULT RI_IReconcileInitiator_SetAbortCallback(
  368. PIReconcileInitiator pirecinit,
  369. PIUnknown piunkForAbort)
  370. {
  371. ASSERT(IS_VALID_STRUCT_PTR(pirecinit, CIReconcileInitiator));
  372. /* piunkForAbort can be legally NULL */
  373. ASSERT(NULL == piunkForAbort || IS_VALID_STRUCT_PTR(piunkForAbort, CIUnknown));
  374. return(ReconcileInitiator_SetAbortCallback(
  375. ClassFromIface(CReconcileInitiator, irecinit, pirecinit),
  376. piunkForAbort));
  377. }
  378. /*
  379. ** RI_IReconcileInitiator_SetProgressFeedback()
  380. **
  381. **
  382. **
  383. ** Arguments:
  384. **
  385. ** Returns:
  386. **
  387. ** Side Effects: none
  388. */
  389. PRIVATE_CODE HRESULT RI_IReconcileInitiator_SetProgressFeedback(
  390. PIReconcileInitiator pirecinit,
  391. ULONG ulProgress,
  392. ULONG ulProgressMax)
  393. {
  394. /* ulProgress may be any value. */
  395. /* ulProgressMax may be any value. */
  396. ASSERT(IS_VALID_STRUCT_PTR(pirecinit, CIReconcileInitiator));
  397. return(ReconcileInitiator_SetProgressFeedback(
  398. ClassFromIface(CReconcileInitiator, irecinit, pirecinit),
  399. ulProgress, ulProgressMax));
  400. }
  401. /*
  402. ** RI_IBriefcaseInitiator_QueryInterface()
  403. **
  404. **
  405. **
  406. ** Arguments:
  407. **
  408. ** Returns:
  409. **
  410. ** Side Effects: none
  411. */
  412. PRIVATE_CODE HRESULT RI_IBriefcaseInitiator_QueryInterface(
  413. PIBriefcaseInitiator pibcinit,
  414. REFIID riid, PVOID *ppvObject)
  415. {
  416. ASSERT(IS_VALID_STRUCT_PTR(pibcinit, CIBriefcaseInitiator));
  417. //ASSERT(IsValidREFIID(riid));
  418. ASSERT(IS_VALID_WRITE_PTR(ppvObject, PVOID));
  419. return(ReconcileInitiator_QueryInterface(
  420. ClassFromIface(CReconcileInitiator, ibcinit, pibcinit),
  421. riid, ppvObject));
  422. }
  423. /*
  424. ** RI_IBriefcaseInitiator_AddRef()
  425. **
  426. **
  427. **
  428. ** Arguments:
  429. **
  430. ** Returns:
  431. **
  432. ** Side Effects: none
  433. */
  434. PRIVATE_CODE ULONG RI_IBriefcaseInitiator_AddRef(PIBriefcaseInitiator pibcinit)
  435. {
  436. ASSERT(IS_VALID_STRUCT_PTR(pibcinit, CIBriefcaseInitiator));
  437. return(ReconcileInitiator_AddRef(
  438. ClassFromIface(CReconcileInitiator, ibcinit, pibcinit)));
  439. }
  440. /*
  441. ** RI_IBriefcaseInitiator_Release()
  442. **
  443. **
  444. **
  445. ** Arguments:
  446. **
  447. ** Returns:
  448. **
  449. ** Side Effects: none
  450. */
  451. PRIVATE_CODE ULONG RI_IBriefcaseInitiator_Release(
  452. PIBriefcaseInitiator pibcinit)
  453. {
  454. ASSERT(IS_VALID_STRUCT_PTR(pibcinit, CIBriefcaseInitiator));
  455. return(ReconcileInitiator_Release(
  456. ClassFromIface(CReconcileInitiator, ibcinit, pibcinit)));
  457. }
  458. /*
  459. ** RI_IBriefcaseInitiator_IsMonikerInBriefcase()
  460. **
  461. **
  462. **
  463. ** Arguments:
  464. **
  465. ** Returns:
  466. **
  467. ** Side Effects: none
  468. */
  469. PRIVATE_CODE HRESULT RI_IBriefcaseInitiator_IsMonikerInBriefcase(
  470. PIBriefcaseInitiator pibcinit,
  471. PIMoniker pmk)
  472. {
  473. ASSERT(IS_VALID_STRUCT_PTR(pibcinit, CIBriefcaseInitiator));
  474. ASSERT(IS_VALID_STRUCT_PTR(pmk, CIMoniker));
  475. return(ReconcileInitiator_IsMonikerInBriefcase(
  476. ClassFromIface(CReconcileInitiator, ibcinit, pibcinit),
  477. pmk));
  478. }
  479. #ifdef DEBUG
  480. /*
  481. ** IsValidPCCReconcileInitiator()
  482. **
  483. **
  484. **
  485. ** Arguments:
  486. **
  487. ** Returns:
  488. **
  489. ** Side Effects: none
  490. */
  491. PRIVATE_CODE BOOL IsValidPCCReconcileInitiator(PCCReconcileInitiator pcrecinit)
  492. {
  493. /* ulcRef may be any value. */
  494. /* lpCallbackData may be any value. */
  495. return(IS_VALID_READ_PTR(pcrecinit, CCReconcileInitiator) &&
  496. IS_VALID_STRUCT_PTR(&(pcrecinit->irecinit), CIReconcileInitiator) &&
  497. IS_VALID_STRUCT_PTR(&(pcrecinit->ibcinit), CIBriefcaseInitiator) &&
  498. IS_VALID_HANDLE(pcrecinit->hbr, BRFCASE) &&
  499. (! pcrecinit->rsp ||
  500. IS_VALID_CODE_PTR(pcrecinit->rsp, RECSTATUSPROC)) &&
  501. (! pcrecinit->piunkForAbort ||
  502. IS_VALID_STRUCT_PTR(pcrecinit->piunkForAbort, CIUnknown)));
  503. }
  504. /*
  505. ** IsValidPCIBriefcaseInitiator()
  506. **
  507. **
  508. **
  509. ** Arguments:
  510. **
  511. ** Returns:
  512. **
  513. ** Side Effects: none
  514. */
  515. PRIVATE_CODE BOOL IsValidPCIBriefcaseInitiator(PCIBriefcaseInitiator pcibcinit)
  516. {
  517. return(IS_VALID_READ_PTR(pcibcinit, CIBriefcaseInitiator) &&
  518. IS_VALID_READ_PTR(pcibcinit->lpVtbl, sizeof(*(pcibcinit->lpVtbl))) &&
  519. IS_VALID_STRUCT_PTR((PCIUnknown)pcibcinit, CIUnknown) &&
  520. IS_VALID_CODE_PTR(pcibcinit->lpVtbl->IsMonikerInBriefcase, IsMonikerInBriefcase));
  521. }
  522. #endif
  523. /****************************** Public Functions *****************************/
  524. /*
  525. ** IReconcileInitiator_Constructor()
  526. **
  527. **
  528. **
  529. ** Arguments:
  530. **
  531. ** Returns:
  532. **
  533. ** Side Effects: none
  534. */
  535. PUBLIC_CODE HRESULT IReconcileInitiator_Constructor(
  536. HBRFCASE hbr, RECSTATUSPROC rsp,
  537. LPARAM lpCallbackData,
  538. PIReconcileInitiator *ppirecinit)
  539. {
  540. HRESULT hr;
  541. PCReconcileInitiator precinit;
  542. /* lpCallbackData may be any value. */
  543. ASSERT(IS_VALID_HANDLE(hbr, BRFCASE));
  544. ASSERT(! rsp ||
  545. IS_VALID_CODE_PTR(rsp, RECSTATUSPROC));
  546. ASSERT(IS_VALID_WRITE_PTR(ppirecinit, PIReconcileInitiator));
  547. if (AllocateMemory(sizeof(*precinit), &precinit))
  548. {
  549. precinit->irecinit.lpVtbl = &Mcirecinitvtbl;
  550. precinit->ibcinit.lpVtbl = &Mcibcinitvtbl;
  551. precinit->ulcRef = 0;
  552. precinit->hbr = hbr;
  553. precinit->rsp = rsp;
  554. precinit->lpCallbackData = lpCallbackData;
  555. precinit->piunkForAbort = NULL;
  556. ASSERT(IS_VALID_STRUCT_PTR(precinit, CCReconcileInitiator));
  557. hr = precinit->irecinit.lpVtbl->QueryInterface(
  558. &(precinit->irecinit), &IID_IReconcileInitiator, ppirecinit);
  559. ASSERT(hr == S_OK);
  560. }
  561. else
  562. hr = E_OUTOFMEMORY;
  563. ASSERT(FAILED(hr) ||
  564. IS_VALID_STRUCT_PTR(*ppirecinit, CIReconcileInitiator));
  565. return(hr);
  566. }