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.

1702 lines
38 KiB

  1. /************************************************************************
  2. Copyright (c) 2000 - 2000 Microsoft Corporation
  3. Module Name :
  4. drizcpat.cpp
  5. Abstract :
  6. Compatibility wrapper against the old AU bits.
  7. Author :
  8. Revision History :
  9. ***********************************************************************/
  10. #include "stdafx.h"
  11. #if !defined(BITS_V12_ON_NT4)
  12. #include "drizcpat.tmh"
  13. #endif
  14. DWORD NewJobSizeToOldSize( UINT64 NewSize )
  15. {
  16. if ( NewSize == UINT64(-1))
  17. return 0;
  18. return (DWORD)NewSize;
  19. }
  20. DWORD MapOldNotifyToNewNotify( DWORD dwOldNotify )
  21. {
  22. // The mars interface has error on by default.
  23. DWORD dwReturnVal = BG_NOTIFY_JOB_ERROR;
  24. if ( dwOldNotify &
  25. ~( QM_NOTIFY_GROUP_DONE | QM_NOTIFY_DISABLE_NOTIFY ) )
  26. throw ComError( E_NOTIMPL );
  27. if ( dwOldNotify & QM_NOTIFY_GROUP_DONE )
  28. dwReturnVal |= BG_NOTIFY_JOB_TRANSFERRED;
  29. if ( dwOldNotify & QM_NOTIFY_DISABLE_NOTIFY )
  30. dwReturnVal |= BG_NOTIFY_DISABLE;
  31. return dwReturnVal;
  32. }
  33. DWORD MapNewNotifyToOldNotify( DWORD dwNewNotify )
  34. {
  35. DWORD dwReturnVal = 0;
  36. if ( dwNewNotify & BG_NOTIFY_JOB_TRANSFERRED )
  37. dwReturnVal |= QM_NOTIFY_GROUP_DONE;
  38. if ( dwNewNotify & BG_NOTIFY_DISABLE )
  39. dwReturnVal |= QM_NOTIFY_DISABLE_NOTIFY;
  40. return dwReturnVal;
  41. }
  42. COldGroupInterface::COldGroupInterface(
  43. CJob *pJob ) :
  44. m_refs(1),
  45. m_ServiceInstance( g_ServiceInstance ),
  46. m_NotifyPointer( NULL ),
  47. m_NotifyClsid( GUID_NULL ),
  48. m_pJob(pJob),
  49. m_pJobExternal( pJob->GetExternalInterface() )
  50. {
  51. m_pJobExternal->AddRef();
  52. }
  53. COldGroupInterface::~COldGroupInterface()
  54. {
  55. m_pJobExternal->Release();
  56. }
  57. STDMETHODIMP
  58. COldGroupInterface::QueryInterface(
  59. REFIID iid,
  60. void** ppvObject
  61. )
  62. {
  63. BEGIN_EXTERNAL_FUNC
  64. LogPublicApiBegin( "iid %!guid!, ppvObject %p", &iid, ppvObject );
  65. HRESULT Hr = S_OK;
  66. *ppvObject = NULL;
  67. if ((iid == _uuidof(IUnknown)) || (iid == __uuidof(IBackgroundCopyGroup)) )
  68. {
  69. *ppvObject = (IBackgroundCopyGroup *)this;
  70. ((IUnknown *)(*ppvObject))->AddRef();
  71. }
  72. else
  73. {
  74. Hr = E_NOINTERFACE;
  75. }
  76. LogPublicApiEnd( "iid %!guid!, ppvObject %p", &iid, ppvObject );
  77. return Hr;
  78. END_EXTERNAL_FUNC
  79. }
  80. ULONG _stdcall
  81. COldGroupInterface::AddRef(void)
  82. {
  83. BEGIN_EXTERNAL_FUNC
  84. ULONG newrefs = InterlockedIncrement(&m_refs);
  85. LogRef( "job %p, refs = %d", m_pJob, newrefs );
  86. return newrefs;
  87. END_EXTERNAL_FUNC
  88. }
  89. ULONG _stdcall
  90. COldGroupInterface::Release(void)
  91. {
  92. BEGIN_EXTERNAL_FUNC
  93. ULONG newrefs = InterlockedDecrement(&m_refs);
  94. LogRef( "job %p, refs = %d", m_pJob, newrefs );
  95. if (newrefs == 0)
  96. {
  97. delete this;
  98. }
  99. return newrefs;
  100. END_EXTERNAL_FUNC
  101. }
  102. STDMETHODIMP
  103. COldGroupInterface::GetPropInternal(
  104. GROUPPROP property,
  105. VARIANT * pVal
  106. )
  107. {
  108. HRESULT Hr = S_OK;
  109. CLockedJobReadPointer LockedJob(m_pJob);
  110. LogPublicApiBegin( "property %u, pVal %p", property, pVal );
  111. WCHAR * pString = NULL;
  112. try
  113. {
  114. ASSERT( pVal );
  115. VariantClear( pVal );
  116. THROW_HRESULT( LockedJob.ValidateAccess() );
  117. switch (property)
  118. {
  119. case GROUPPROP_PRIORITY:
  120. pVal->vt = VT_INT;
  121. pVal->intVal = 1;
  122. break;
  123. case GROUPPROP_PROTOCOLFLAGS:
  124. pVal->vt = VT_INT;
  125. pVal->intVal = QM_PROTOCOL_HTTP;
  126. break;
  127. case GROUPPROP_NOTIFYFLAGS:
  128. pVal->vt = VT_INT;
  129. pVal->intVal = MapNewNotifyToOldNotify( LockedJob->GetNotifyFlags() );
  130. break;
  131. case GROUPPROP_NOTIFYCLSID:
  132. {
  133. THROW_HRESULT( StringFromIID( m_NotifyClsid, &pString ));
  134. pVal->vt = VT_BSTR;
  135. pVal->bstrVal = SysAllocString( pString );
  136. if ( !pVal->bstrVal )
  137. throw ComError( E_OUTOFMEMORY );
  138. break;
  139. }
  140. case GROUPPROP_DISPLAYNAME:
  141. {
  142. THROW_HRESULT( LockedJob->GetDisplayName( &pString ) );
  143. pVal->vt = VT_BSTR;
  144. pVal->bstrVal = SysAllocString( pString );
  145. if ( !pVal->bstrVal )
  146. throw ComError( E_OUTOFMEMORY );
  147. break;
  148. }
  149. case GROUPPROP_DESCRIPTION:
  150. {
  151. THROW_HRESULT( LockedJob->GetDescription( &pString ) );
  152. pVal->vt = VT_BSTR;
  153. pVal->bstrVal = SysAllocString( pString );
  154. if ( !pVal->bstrVal )
  155. throw ComError( E_OUTOFMEMORY );
  156. break;
  157. }
  158. default:
  159. return E_NOTIMPL;
  160. }
  161. }
  162. catch( ComError Error )
  163. {
  164. Hr = Error.Error();
  165. VariantClear( pVal );
  166. }
  167. CoTaskMemFree( pString );
  168. LogPublicApiEnd( "property %u, pVal %p", property, pVal );
  169. return Hr;
  170. }
  171. STDMETHODIMP
  172. COldGroupInterface::SetPropInternal(
  173. GROUPPROP property,
  174. VARIANT *pvarVal
  175. )
  176. {
  177. HRESULT Hr = S_OK;
  178. CLockedJobWritePointer LockedJob(m_pJob);
  179. LogPublicApiBegin( "property %u, Val %p", property, pvarVal );
  180. DWORD dwValue = -1;
  181. BSTR bstrIn = NULL;
  182. try
  183. {
  184. if (!pvarVal)
  185. throw ComError(E_INVALIDARG);
  186. THROW_HRESULT( LockedJob.ValidateAccess() );
  187. //
  188. // This is how the old code did it. Unfortunate, but compatible.
  189. //
  190. switch (pvarVal->vt)
  191. {
  192. case VT_I4:
  193. dwValue = (DWORD)(pvarVal->lVal < 0) ? -1 : pvarVal->lVal;
  194. break;
  195. case VT_I2:
  196. dwValue = (DWORD)(pvarVal->iVal < 0) ? -1 : pvarVal->iVal;
  197. break;
  198. case VT_UI2:
  199. dwValue = (DWORD)pvarVal->uiVal;
  200. break;
  201. case VT_UI4:
  202. dwValue = (DWORD)pvarVal->ulVal;
  203. break;
  204. case VT_INT:
  205. dwValue = (DWORD)(pvarVal->intVal < 0) ? -1 : pvarVal->intVal;
  206. break;
  207. case VT_UINT:
  208. dwValue = (DWORD)pvarVal->uintVal;
  209. break;
  210. case VT_BSTR:
  211. bstrIn = pvarVal->bstrVal;
  212. break;
  213. default:
  214. return E_INVALIDARG;
  215. }
  216. switch (property)
  217. {
  218. case GROUPPROP_PRIORITY:
  219. //
  220. // Only one priority was supported. No need to store it.
  221. //
  222. if (dwValue != 1)
  223. {
  224. throw ComError( E_NOTIMPL );
  225. }
  226. break;
  227. case GROUPPROP_PROTOCOLFLAGS:
  228. //
  229. // Only HTTP was supported. No need to store it.
  230. //
  231. if (dwValue != QM_PROTOCOL_HTTP)
  232. {
  233. throw ComError( E_NOTIMPL );
  234. }
  235. break;
  236. case GROUPPROP_NOTIFYFLAGS:
  237. THROW_HRESULT( LockedJob->SetNotifyFlags( MapOldNotifyToNewNotify( dwValue ) ) );
  238. break;
  239. case GROUPPROP_NOTIFYCLSID:
  240. {
  241. if (NULL == bstrIn)
  242. {
  243. throw ComError( E_INVALIDARG );
  244. }
  245. GUID clsid;
  246. THROW_HRESULT( IIDFromString( bstrIn, &clsid ) );
  247. m_NotifyClsid = clsid;
  248. break;
  249. }
  250. case GROUPPROP_DISPLAYNAME:
  251. THROW_HRESULT( LockedJob->SetDisplayName( (WCHAR *)bstrIn ) );
  252. break;
  253. case GROUPPROP_DESCRIPTION:
  254. THROW_HRESULT( LockedJob->SetDescription( (WCHAR *)bstrIn ) );
  255. break;
  256. default:
  257. return E_NOTIMPL;
  258. }
  259. }
  260. catch( ComError Error )
  261. {
  262. Hr = Error.Error();
  263. }
  264. LogPublicApiEnd( "property %u, pVal %p", property, pvarVal );
  265. return Hr;
  266. }
  267. STDMETHODIMP
  268. COldGroupInterface::GetProgressInternal(
  269. DWORD flags,
  270. DWORD * pProgress
  271. )
  272. {
  273. HRESULT Hr = S_OK;
  274. CLockedJobReadPointer LockedJob(m_pJob);
  275. LogPublicApiBegin( "flags %u", flags );
  276. try
  277. {
  278. ASSERT( pProgress );
  279. THROW_HRESULT( LockedJob.ValidateAccess() );
  280. BG_JOB_PROGRESS JobProgress;
  281. LockedJob->GetProgress( &JobProgress );
  282. switch( flags )
  283. {
  284. case QM_PROGRESS_SIZE_DONE:
  285. {
  286. *pProgress = NewJobSizeToOldSize( JobProgress.BytesTransferred );
  287. break;
  288. }
  289. case QM_PROGRESS_PERCENT_DONE:
  290. {
  291. if ( ( -1 == JobProgress.BytesTotal ) ||
  292. ( -1 == JobProgress.BytesTransferred ) ||
  293. ( 0 == JobProgress.BytesTotal ) )
  294. {
  295. *pProgress = 0;
  296. }
  297. else
  298. {
  299. double ratio = double(JobProgress.BytesTransferred) / double(JobProgress.BytesTotal );
  300. *pProgress = DWORD( ratio * 100.0 );
  301. }
  302. break;
  303. }
  304. default:
  305. {
  306. throw ComError( E_NOTIMPL );
  307. }
  308. }
  309. }
  310. catch( ComError Error )
  311. {
  312. Hr = Error.Error();
  313. *pProgress = 0;
  314. }
  315. LogPublicApiEnd( "progress %d", *pProgress );
  316. return Hr;
  317. }
  318. STDMETHODIMP
  319. COldGroupInterface::GetStatusInternal(
  320. DWORD *pdwStatus,
  321. DWORD *pdwJobIndex)
  322. {
  323. HRESULT Hr = S_OK;
  324. CLockedJobReadPointer LockedJob(m_pJob);
  325. LogPublicApiBegin( "pdwStatus %p, pdwJobIndex %p", pdwStatus, pdwJobIndex );
  326. try
  327. {
  328. ASSERT( pdwStatus && pdwJobIndex );
  329. *pdwStatus = *pdwJobIndex = 0;
  330. THROW_HRESULT( LockedJob.ValidateAccess() );
  331. // Note: we never increment the JobIndex anymore
  332. BG_JOB_STATE State = LockedJob->_GetState();
  333. BG_JOB_PRIORITY Priority = LockedJob->_GetPriority();
  334. if ( BG_JOB_PRIORITY_FOREGROUND == Priority )
  335. *pdwStatus |= QM_STATUS_GROUP_FOREGROUND;
  336. switch( State )
  337. {
  338. case BG_JOB_STATE_QUEUED:
  339. case BG_JOB_STATE_CONNECTING:
  340. case BG_JOB_STATE_TRANSFERRING:
  341. *pdwStatus |= QM_STATUS_GROUP_INCOMPLETE;
  342. break;
  343. case BG_JOB_STATE_SUSPENDED:
  344. *pdwStatus |= ( QM_STATUS_GROUP_SUSPENDED | QM_STATUS_GROUP_INCOMPLETE );
  345. break;
  346. case BG_JOB_STATE_ERROR:
  347. *pdwStatus |= ( QM_STATUS_GROUP_ERROR | QM_STATUS_GROUP_INCOMPLETE | QM_STATUS_GROUP_SUSPENDED );
  348. break;
  349. case BG_JOB_STATE_TRANSIENT_ERROR:
  350. *pdwStatus |= ( QM_STATUS_GROUP_INCOMPLETE );
  351. break;
  352. case BG_JOB_STATE_TRANSFERRED:
  353. *pdwStatus |= ( QM_STATUS_GROUP_COMPLETE | QM_STATUS_GROUP_SUSPENDED );
  354. break;
  355. case BG_JOB_STATE_ACKNOWLEDGED:
  356. *pdwStatus |= ( QM_STATUS_GROUP_COMPLETE | QM_STATUS_GROUP_SUSPENDED );
  357. break;
  358. case BG_JOB_STATE_CANCELLED:
  359. break;
  360. }
  361. }
  362. catch( ComError Error )
  363. {
  364. Hr = Error.Error();
  365. *pdwStatus = 0;
  366. }
  367. LogPublicApiEnd( "pdwStatus %p, pdwJobIndex %p", pdwStatus, pdwJobIndex );
  368. return Hr;
  369. }
  370. STDMETHODIMP
  371. COldGroupInterface::GetJobInternal(
  372. GUID jobID,
  373. IBackgroundCopyJob1 **ppJob)
  374. {
  375. HRESULT Hr = S_OK;
  376. CLockedJobReadPointer LockedJob(m_pJob);
  377. LogPublicApiBegin( "jobID %!guid!, ppJob %p", &jobID, ppJob );
  378. try
  379. {
  380. ASSERT( ppJob );
  381. *ppJob = NULL;
  382. THROW_HRESULT( LockedJob.ValidateAccess() );
  383. COldJobInterface *pOldJob = m_pJob->GetOldExternalJobInterface();
  384. if (!pOldJob)
  385. throw ComError( QM_E_ITEM_NOT_FOUND );
  386. if (jobID != pOldJob->GetOldJobId() )
  387. throw ComError( QM_E_ITEM_NOT_FOUND );
  388. *ppJob = pOldJob;
  389. (*ppJob)->AddRef();
  390. }
  391. catch( ComError Error )
  392. {
  393. Hr = Error.Error();
  394. }
  395. LogPublicApiEnd( "jobID %!guid!, ppJob %p", &jobID, ppJob );
  396. return Hr;
  397. }
  398. STDMETHODIMP
  399. COldGroupInterface::SuspendGroupInternal(
  400. )
  401. {
  402. HRESULT Hr = S_OK;
  403. CLockedJobWritePointer LockedJob(m_pJob);
  404. LogPublicApiBegin( "void" );
  405. try
  406. {
  407. THROW_HRESULT( LockedJob.ValidateAccess() );
  408. THROW_HRESULT( LockedJob->Suspend() );
  409. }
  410. catch( ComError Error )
  411. {
  412. Hr = Error.Error();
  413. }
  414. LogPublicApiEnd( "void" );
  415. return Hr;
  416. }
  417. STDMETHODIMP
  418. COldGroupInterface::ResumeGroupInternal(
  419. )
  420. {
  421. HRESULT Hr = S_OK;
  422. CLockedJobWritePointer LockedJob(m_pJob);
  423. LogPublicApiBegin( " " );
  424. try
  425. {
  426. THROW_HRESULT( LockedJob.ValidateAccess() );
  427. THROW_HRESULT( LockedJob->Resume() );
  428. }
  429. catch( ComError Error )
  430. {
  431. Hr = Error.Error();
  432. }
  433. LogPublicApiEnd( " " );
  434. return Hr;
  435. }
  436. STDMETHODIMP
  437. COldGroupInterface::CancelGroupInternal(
  438. )
  439. {
  440. HRESULT Hr = S_OK;
  441. CLockedJobWritePointer LockedJob(m_pJob);
  442. LogPublicApiBegin( " " );
  443. try
  444. {
  445. THROW_HRESULT( LockedJob.ValidateAccess() );
  446. THROW_HRESULT( LockedJob->Complete() );
  447. }
  448. catch( ComError Error )
  449. {
  450. Hr = Error.Error();
  451. }
  452. LogPublicApiEnd( " " );
  453. return Hr;
  454. }
  455. STDMETHODIMP
  456. COldGroupInterface::get_SizeInternal(
  457. DWORD *pdwSize
  458. )
  459. {
  460. HRESULT Hr = S_OK;
  461. CLockedJobReadPointer LockedJob(m_pJob);
  462. LogPublicApiBegin( " " );
  463. try
  464. {
  465. ASSERT( pdwSize );
  466. THROW_HRESULT( LockedJob.ValidateAccess() );
  467. BG_JOB_PROGRESS Progress;
  468. LockedJob->GetProgress( &Progress );
  469. *pdwSize = NewJobSizeToOldSize( Progress.BytesTotal );
  470. }
  471. catch( ComError Error )
  472. {
  473. Hr = Error.Error();
  474. *pdwSize = 0;
  475. }
  476. LogPublicApiEnd( "dwSize %d", *pdwSize );
  477. return Hr;
  478. }
  479. STDMETHODIMP
  480. COldGroupInterface::get_GroupIDInternal(
  481. GUID *pguidGroupID )
  482. {
  483. HRESULT Hr = S_OK;
  484. CLockedJobReadPointer LockedJob(m_pJob);
  485. LogPublicApiBegin( " " );
  486. try
  487. {
  488. ASSERT( pguidGroupID );
  489. THROW_HRESULT( LockedJob.ValidateAccess() );
  490. *pguidGroupID = LockedJob->GetId();
  491. }
  492. catch( ComError Error )
  493. {
  494. Hr = Error.Error();
  495. memset( pguidGroupID, 0 , sizeof(*pguidGroupID) );
  496. }
  497. LogPublicApiEnd( "id %!guid!", pguidGroupID );
  498. return Hr;
  499. }
  500. STDMETHODIMP
  501. COldGroupInterface::CreateJobInternal(
  502. GUID guidJobID,
  503. IBackgroundCopyJob1 **ppJob )
  504. {
  505. HRESULT Hr = S_OK;
  506. CLockedJobWritePointer LockedJob(m_pJob);
  507. LogPublicApiBegin( "guidJobID %!guid!", &guidJobID );
  508. try
  509. {
  510. ASSERT( ppJob );
  511. *ppJob = NULL;
  512. THROW_HRESULT( LockedJob.ValidateAccess() );
  513. BG_JOB_STATE State = LockedJob->_GetState();
  514. switch( State )
  515. {
  516. case BG_JOB_STATE_QUEUED:
  517. case BG_JOB_STATE_CONNECTING:
  518. case BG_JOB_STATE_TRANSFERRING:
  519. throw ComError( QM_E_INVALID_STATE );
  520. break;
  521. case BG_JOB_STATE_SUSPENDED:
  522. case BG_JOB_STATE_ERROR:
  523. break;
  524. case BG_JOB_STATE_TRANSIENT_ERROR:
  525. case BG_JOB_STATE_TRANSFERRED:
  526. case BG_JOB_STATE_ACKNOWLEDGED:
  527. case BG_JOB_STATE_CANCELLED:
  528. throw ComError( QM_E_INVALID_STATE );
  529. break;
  530. default:
  531. throw ComError( QM_E_INVALID_STATE );
  532. break;
  533. }
  534. if (LockedJob->GetOldExternalJobInterface())
  535. throw ComError( E_NOTIMPL );
  536. COldJobInterface *pOldJob = new COldJobInterface( guidJobID, m_pJob );
  537. LockedJob->SetOldExternalJobInterface( pOldJob );
  538. *ppJob = pOldJob;
  539. (*ppJob)->AddRef();
  540. g_Manager->Serialize();
  541. }
  542. catch( ComError Error )
  543. {
  544. Hr = Error.Error();
  545. }
  546. LogPublicApiEnd( "ppJob %p", *ppJob );
  547. return Hr;
  548. }
  549. STDMETHODIMP
  550. COldGroupInterface::EnumJobsInternal(
  551. DWORD dwFlags,
  552. IEnumBackgroundCopyJobs1 **ppEnumJobs )
  553. {
  554. HRESULT Hr = S_OK;
  555. CLockedJobReadPointer LockedJob(m_pJob);
  556. LogPublicApiBegin( "dwFlags %u, ppEnumJobs %p", dwFlags, ppEnumJobs );
  557. CEnumOldJobs* pEnum = NULL;
  558. try
  559. {
  560. ASSERT( ppEnumJobs );
  561. *ppEnumJobs = NULL;
  562. THROW_HRESULT( LockedJob.ValidateAccess() );
  563. if (dwFlags)
  564. throw ComError( E_NOTIMPL );
  565. pEnum = new CEnumOldJobs;
  566. COldJobInterface *pOldJob = LockedJob->GetOldExternalJobInterface();
  567. if (pOldJob)
  568. {
  569. GUID guid = pOldJob->GetOldJobId();
  570. pEnum->Add( guid );
  571. }
  572. *ppEnumJobs = pEnum;
  573. }
  574. catch( ComError Error )
  575. {
  576. Hr = Error.Error();
  577. }
  578. LogPublicApiEnd( "dwFlags %u, ppEnumJobs %p", dwFlags, ppEnumJobs );
  579. return Hr;
  580. }
  581. STDMETHODIMP
  582. COldGroupInterface::SwitchToForegroundInternal(
  583. )
  584. {
  585. HRESULT Hr = S_OK;
  586. CLockedJobWritePointer LockedJob(m_pJob);
  587. LogPublicApiBegin( " " );
  588. try
  589. {
  590. THROW_HRESULT( LockedJob.ValidateAccess() );
  591. THROW_HRESULT( LockedJob->SetPriority( BG_JOB_PRIORITY_FOREGROUND ) );
  592. }
  593. catch( ComError Error )
  594. {
  595. Hr = Error.Error();
  596. }
  597. LogPublicApiEnd( " " );
  598. return Hr;
  599. }
  600. STDMETHODIMP
  601. COldGroupInterface::QueryNewJobInterface(
  602. REFIID iid,
  603. IUnknown **pUnk
  604. )
  605. {
  606. LogInfo("QueryNewJobInterface %!guid!", &iid);
  607. if (iid != __uuidof(IBackgroundCopyJob))
  608. {
  609. LogError("E_NOTIMPL");
  610. *pUnk = NULL;
  611. return E_NOTIMPL;
  612. }
  613. *pUnk = m_pJob->GetExternalInterface();
  614. (*pUnk)->AddRef();
  615. LogInfo("OK");
  616. return S_OK;
  617. }
  618. STDMETHODIMP
  619. COldGroupInterface::SetNotificationPointer(
  620. REFIID iid,
  621. IUnknown *pUnk
  622. )
  623. {
  624. HRESULT Hr = S_OK;
  625. IBackgroundCopyCallback1 *pICB = NULL;
  626. LogPublicApiBegin( "IID %!guid! ptr %p", &iid, pUnk );
  627. if (iid != __uuidof(IBackgroundCopyCallback1))
  628. {
  629. Hr = E_NOTIMPL;
  630. }
  631. else if ( pUnk )
  632. {
  633. try
  634. {
  635. CNestedImpersonation imp;
  636. //
  637. // Gotta do it twice, because SwitchToLogonToken will fail
  638. // if the user is not interactively logged in.
  639. //
  640. THROW_HRESULT( SetStaticCloaking( pUnk ) );
  641. imp.SwitchToLogonToken();
  642. THROW_HRESULT( SetStaticCloaking( pUnk ) );
  643. THROW_HRESULT( pUnk->QueryInterface( iid, (void**)&pICB ) );
  644. THROW_HRESULT( SetStaticCloaking( pICB ) );
  645. SafeRelease( m_NotifyPointer );
  646. m_NotifyPointer = pICB;
  647. }
  648. catch( ComError Error )
  649. {
  650. SafeRelease( pICB );
  651. Hr = Error.Error();
  652. }
  653. }
  654. LogPublicApiEnd( " " );
  655. return Hr;
  656. }
  657. IBackgroundCopyCallback1 *
  658. COldGroupInterface::GetNotificationPointer()
  659. {
  660. if (m_NotifyPointer)
  661. {
  662. m_NotifyPointer->AddRef();
  663. }
  664. return m_NotifyPointer;
  665. }
  666. void
  667. COldGroupInterface::Serialize(
  668. HANDLE hFile
  669. )
  670. {
  671. SafeWriteFile( hFile, m_NotifyClsid );
  672. if ( m_pJob->GetOldExternalJobInterface() )
  673. {
  674. SafeWriteFile( hFile, (bool)true );
  675. m_pJob->GetOldExternalJobInterface()->Serialize( hFile );
  676. }
  677. else
  678. {
  679. SafeWriteFile( hFile, (bool)false );
  680. }
  681. return;
  682. }
  683. COldGroupInterface *
  684. COldGroupInterface::UnSerialize(
  685. HANDLE hFile,
  686. CJob* Job
  687. )
  688. {
  689. COldGroupInterface * group = NULL;
  690. try
  691. {
  692. group = new COldGroupInterface(Job);
  693. if (!group)
  694. {
  695. throw ComError( E_OUTOFMEMORY );
  696. }
  697. SafeReadFile( hFile, &group->m_NotifyClsid );
  698. bool bHasOldExternalJobInterface;
  699. SafeReadFile( hFile, &bHasOldExternalJobInterface );
  700. if ( bHasOldExternalJobInterface )
  701. {
  702. COldJobInterface *OldJobInterface = COldJobInterface::Unserialize( hFile, Job );
  703. Job->SetOldExternalJobInterface( OldJobInterface );
  704. }
  705. }
  706. catch ( ComError Error )
  707. {
  708. delete group;
  709. throw;
  710. }
  711. return group;
  712. }
  713. COldJobInterface::COldJobInterface(
  714. GUID JobGuid,
  715. CJob *pJob ) :
  716. m_refs(1),
  717. m_ServiceInstance( g_ServiceInstance ),
  718. m_OldJobGuid( JobGuid ),
  719. m_pJob( pJob ),
  720. m_pJobExternal( pJob->GetExternalInterface() )
  721. {
  722. m_pJobExternal->AddRef();
  723. }
  724. COldJobInterface::~COldJobInterface()
  725. {
  726. m_pJobExternal->Release();
  727. }
  728. STDMETHODIMP
  729. COldJobInterface::QueryInterface(
  730. REFIID iid,
  731. void** ppvObject
  732. )
  733. {
  734. BEGIN_EXTERNAL_FUNC
  735. LogPublicApiBegin( "iid %!guid!, ppvObject %p", &iid, ppvObject );
  736. HRESULT Hr = S_OK;
  737. *ppvObject = NULL;
  738. if ((iid == _uuidof(IUnknown)) || (iid == __uuidof(IBackgroundCopyJob1)) )
  739. {
  740. *ppvObject = (IBackgroundCopyJob1 *)this;
  741. ((IUnknown *)(*ppvObject))->AddRef();
  742. }
  743. else
  744. {
  745. Hr = E_NOINTERFACE;
  746. }
  747. LogPublicApiEnd( "iid %!guid!, ppvObject %p", &iid, ppvObject );
  748. return Hr;
  749. END_EXTERNAL_FUNC
  750. }
  751. ULONG _stdcall
  752. COldJobInterface::AddRef(void)
  753. {
  754. BEGIN_EXTERNAL_FUNC
  755. ULONG newrefs = InterlockedIncrement(&m_refs);
  756. LogRef( "job %p, refs = %d", m_pJob, newrefs );
  757. return newrefs;
  758. END_EXTERNAL_FUNC
  759. }
  760. ULONG _stdcall
  761. COldJobInterface::Release(void)
  762. {
  763. BEGIN_EXTERNAL_FUNC
  764. ULONG newrefs = InterlockedDecrement(&m_refs);
  765. LogRef( "job %p, refs = %d", m_pJob, newrefs );
  766. if (newrefs == 0)
  767. {
  768. delete this;
  769. }
  770. return newrefs;
  771. END_EXTERNAL_FUNC
  772. }
  773. STDMETHODIMP
  774. COldJobInterface::AddFilesInternal(
  775. ULONG cFileCount,
  776. FILESETINFO **ppFileSet
  777. )
  778. {
  779. HRESULT Hr = S_OK;
  780. CLockedJobWritePointer LockedJob(m_pJob);
  781. LogPublicApiBegin( "cFileCount %u, ppFileSet %p", cFileCount, ppFileSet );
  782. BG_FILE_INFO *pFileInfo = NULL;
  783. try
  784. {
  785. ASSERT( ppFileSet );
  786. THROW_HRESULT( LockedJob.ValidateAccess() );
  787. pFileInfo = new BG_FILE_INFO[cFileCount];
  788. if (!pFileInfo )
  789. {
  790. throw ComError(E_OUTOFMEMORY);
  791. }
  792. for(ULONG c = 0; c < cFileCount; c++ )
  793. {
  794. if ( !ppFileSet[c])
  795. throw ComError(E_INVALIDARG);
  796. // BSTRS act like WCHAR *
  797. pFileInfo[c].LocalName = LPWSTR( (ppFileSet[c])->bstrLocalFile );
  798. pFileInfo[c].RemoteName = LPWSTR( (ppFileSet[c])->bstrRemoteFile );
  799. }
  800. THROW_HRESULT( LockedJob->AddFileSet( cFileCount,
  801. pFileInfo ) );
  802. }
  803. catch(ComError Error )
  804. {
  805. Hr = Error.Error();
  806. }
  807. // Should handle NULL
  808. delete[] pFileInfo;
  809. LogPublicApiEnd( "cFileCount %u, ppFileSet %p", cFileCount, ppFileSet );
  810. return Hr;
  811. }
  812. STDMETHODIMP
  813. COldJobInterface::GetFileCountInternal(
  814. DWORD * pCount
  815. )
  816. {
  817. HRESULT Hr = S_OK;
  818. CLockedJobReadPointer LockedJob(m_pJob);
  819. LogPublicApiBegin( "pCount %p", pCount );
  820. try
  821. {
  822. ASSERT( pCount );
  823. THROW_HRESULT( LockedJob.ValidateAccess() );
  824. BG_JOB_PROGRESS JobProgress;
  825. LockedJob->GetProgress( &JobProgress );
  826. *pCount = JobProgress.FilesTotal;
  827. }
  828. catch(ComError Error )
  829. {
  830. Hr = Error.Error();
  831. *pCount = 0;
  832. }
  833. LogPublicApiEnd( "pCount %p", pCount );
  834. return Hr;
  835. }
  836. STDMETHODIMP
  837. COldJobInterface::GetFileInternal(
  838. ULONG cFileIndex,
  839. FILESETINFO *pFileInfo
  840. )
  841. {
  842. HRESULT Hr = S_OK;
  843. CLockedJobReadPointer LockedJob(m_pJob);
  844. LogPublicApiBegin( "cFileIndex %u, pFileInfo %p", cFileIndex, pFileInfo );
  845. WCHAR *pLocalName = NULL;
  846. WCHAR *pRemoteName = NULL;
  847. try
  848. {
  849. ASSERT( pFileInfo );
  850. memset( pFileInfo, 0, sizeof(FILESETINFO) );
  851. THROW_HRESULT( LockedJob.ValidateAccess() );
  852. CFile *pFile = LockedJob->_GetFileIndex( cFileIndex );
  853. if (!pFile)
  854. throw ComError ( QM_E_ITEM_NOT_FOUND );
  855. THROW_HRESULT( pFile->GetLocalName( &pLocalName ) );
  856. THROW_HRESULT( pFile->GetRemoteName( &pRemoteName ) );
  857. pFileInfo->bstrLocalFile = SysAllocString( pLocalName );
  858. pFileInfo->bstrRemoteFile = SysAllocString( pRemoteName );
  859. if ( !pFileInfo->bstrLocalFile ||
  860. !pFileInfo->bstrRemoteFile )
  861. throw ComError( E_OUTOFMEMORY );
  862. BG_FILE_PROGRESS FileProgress;
  863. pFile->GetProgress( &FileProgress );
  864. pFileInfo->dwSizeHint = NewJobSizeToOldSize( FileProgress.BytesTotal );
  865. }
  866. catch ( ComError Error )
  867. {
  868. Hr = Error.Error();
  869. if ( pFileInfo )
  870. {
  871. SysFreeString( pFileInfo->bstrLocalFile );
  872. SysFreeString( pFileInfo->bstrRemoteFile );
  873. memset( pFileInfo, 0, sizeof(FILESETINFO) );
  874. }
  875. }
  876. // CoTaskMemFree handles NULL
  877. CoTaskMemFree( pLocalName );
  878. CoTaskMemFree( pRemoteName );
  879. LogPublicApiEnd( "cFileIndex %u, pFileInfo %p", cFileIndex, pFileInfo );
  880. return Hr;
  881. }
  882. STDMETHODIMP
  883. COldJobInterface::CancelJobInternal()
  884. {
  885. HRESULT Hr = E_NOTIMPL;
  886. LogPublicApiBegin( "void" );
  887. LogPublicApiEnd( "void" );
  888. return Hr;
  889. }
  890. STDMETHODIMP
  891. COldJobInterface::get_JobIDInternal(
  892. GUID * pId
  893. )
  894. {
  895. HRESULT Hr = S_OK;
  896. CLockedJobReadPointer LockedJob(m_pJob);
  897. LogPublicApiBegin( "pId %p", pId );
  898. try
  899. {
  900. ASSERT( pId );
  901. THROW_HRESULT( LockedJob.ValidateAccess() );
  902. *pId = GetOldJobId();
  903. }
  904. catch(ComError Error )
  905. {
  906. Hr = Error.Error();
  907. memset( pId, 0, sizeof(*pId) );
  908. }
  909. LogPublicApiEnd( "pId %p", pId );
  910. return Hr;
  911. }
  912. STDMETHODIMP
  913. COldJobInterface::GetProgressInternal(
  914. DWORD flags,
  915. DWORD * pProgress
  916. )
  917. {
  918. HRESULT Hr = S_OK;
  919. CLockedJobReadPointer LockedJob(m_pJob);
  920. LogPublicApiBegin( "flags %u, pProgress %p", flags, pProgress );
  921. try
  922. {
  923. ASSERT( pProgress );
  924. *pProgress = NULL;
  925. THROW_HRESULT( LockedJob.ValidateAccess() );
  926. BG_JOB_PROGRESS JobProgress;
  927. LockedJob->GetProgress( &JobProgress );
  928. switch (flags)
  929. {
  930. case QM_PROGRESS_SIZE_DONE:
  931. {
  932. *pProgress = NewJobSizeToOldSize( JobProgress.BytesTransferred );
  933. break;
  934. }
  935. case QM_PROGRESS_PERCENT_DONE:
  936. {
  937. if ( ( -1 == JobProgress.BytesTotal ) ||
  938. ( -1 == JobProgress.BytesTransferred ) ||
  939. ( 0 == JobProgress.BytesTotal ) )
  940. {
  941. *pProgress = 0;
  942. }
  943. else
  944. {
  945. double ratio = double(JobProgress.BytesTransferred) / double(JobProgress.BytesTotal );
  946. *pProgress = DWORD( ratio * 100.0 );
  947. }
  948. break;
  949. }
  950. default:
  951. {
  952. throw ComError( E_NOTIMPL );
  953. }
  954. }
  955. }
  956. catch( ComError Error )
  957. {
  958. Hr = Error.Error();
  959. }
  960. LogPublicApiEnd( "flags %u, pProgress %p", flags, pProgress );
  961. return Hr;
  962. }
  963. STDMETHODIMP
  964. COldJobInterface::SwitchToForegroundInternal()
  965. {
  966. HRESULT Hr = S_OK;
  967. CLockedJobWritePointer LockedJob(m_pJob);
  968. LogPublicApiBegin( "void" );
  969. try
  970. {
  971. THROW_HRESULT( LockedJob.ValidateAccess() );
  972. Hr = E_NOTIMPL;
  973. }
  974. catch( ComError Error )
  975. {
  976. Hr = Error.Error();
  977. }
  978. LogPublicApiEnd( "void" );
  979. return Hr;
  980. }
  981. STDMETHODIMP
  982. COldJobInterface::GetStatusInternal(
  983. DWORD *pdwStatus,
  984. DWORD *pdwWin32Result,
  985. DWORD *pdwTransportResult,
  986. DWORD *pdwNumOfRetries
  987. )
  988. {
  989. HRESULT Hr = S_OK;
  990. CLockedJobReadPointer LockedJob(m_pJob);
  991. LogPublicApiBegin( "pdwStatus %p, pdwWin32Result %p, pdwTransportResult %p, pdwNumOfRetries %p",
  992. pdwStatus, pdwWin32Result, pdwTransportResult, pdwNumOfRetries );
  993. try
  994. {
  995. ASSERT( pdwStatus && pdwWin32Result &&
  996. pdwTransportResult && pdwNumOfRetries );
  997. *pdwStatus = *pdwWin32Result = *pdwTransportResult = *pdwNumOfRetries = 0;
  998. THROW_HRESULT( LockedJob.ValidateAccess() );
  999. BG_JOB_PRIORITY Priority = LockedJob->_GetPriority();
  1000. BG_JOB_STATE State = LockedJob->_GetState();
  1001. THROW_HRESULT( LockedJob->GetErrorCount( pdwNumOfRetries ) );
  1002. if ( BG_JOB_PRIORITY_FOREGROUND == Priority )
  1003. *pdwStatus |= QM_STATUS_JOB_FOREGROUND;
  1004. switch( State )
  1005. {
  1006. case BG_JOB_STATE_QUEUED:
  1007. case BG_JOB_STATE_CONNECTING:
  1008. case BG_JOB_STATE_TRANSFERRING:
  1009. *pdwStatus |= QM_STATUS_JOB_INCOMPLETE;
  1010. break;
  1011. case BG_JOB_STATE_SUSPENDED:
  1012. *pdwStatus |= QM_STATUS_JOB_INCOMPLETE;
  1013. break;
  1014. case BG_JOB_STATE_ERROR:
  1015. *pdwStatus |= QM_STATUS_JOB_ERROR;
  1016. break;
  1017. case BG_JOB_STATE_TRANSIENT_ERROR:
  1018. *pdwStatus |= QM_STATUS_JOB_INCOMPLETE;
  1019. break;
  1020. case BG_JOB_STATE_TRANSFERRED:
  1021. *pdwStatus |= QM_STATUS_JOB_COMPLETE;
  1022. break;
  1023. case BG_JOB_STATE_ACKNOWLEDGED:
  1024. *pdwStatus |= QM_STATUS_JOB_COMPLETE;
  1025. break;
  1026. case BG_JOB_STATE_CANCELLED:
  1027. break;
  1028. default:
  1029. ASSERT(0);
  1030. break;
  1031. }
  1032. if ( BG_JOB_STATE_ERROR == State )
  1033. {
  1034. const CJobError * pError = LockedJob->GetError();
  1035. ASSERT( pError );
  1036. if ( pError )
  1037. {
  1038. pError->GetOldInterfaceErrors( pdwWin32Result, pdwTransportResult );
  1039. }
  1040. }
  1041. }
  1042. catch( ComError Error )
  1043. {
  1044. Hr = Error.Error();
  1045. *pdwStatus = 0;
  1046. *pdwWin32Result = 0;
  1047. *pdwTransportResult = 0;
  1048. *pdwNumOfRetries = 0;
  1049. }
  1050. LogPublicApiEnd( "pdwStatus %p, pdwWin32Result %p, pdwTransportResult %p, pdwNumOfRetries %p",
  1051. pdwStatus, pdwWin32Result, pdwTransportResult, pdwNumOfRetries );
  1052. return Hr;
  1053. }
  1054. void
  1055. COldJobInterface::Serialize(
  1056. HANDLE hFile
  1057. )
  1058. {
  1059. SafeWriteFile( hFile, m_OldJobGuid );
  1060. }
  1061. COldJobInterface *
  1062. COldJobInterface::Unserialize(
  1063. HANDLE hFile,
  1064. CJob* Job
  1065. )
  1066. {
  1067. COldJobInterface * OldJob = NULL;
  1068. try
  1069. {
  1070. GUID OldJobGuid;
  1071. SafeReadFile( hFile, &OldJobGuid );
  1072. OldJob = new COldJobInterface( OldJobGuid, Job );
  1073. if (!OldJob)
  1074. {
  1075. throw ComError( E_OUTOFMEMORY );
  1076. }
  1077. }
  1078. catch ( ComError Error )
  1079. {
  1080. delete OldJob;
  1081. throw;
  1082. }
  1083. return OldJob;
  1084. }
  1085. COldQmgrInterface::COldQmgrInterface() :
  1086. m_refs(1),
  1087. m_ServiceInstance( g_ServiceInstance )
  1088. {
  1089. }
  1090. STDMETHODIMP
  1091. COldQmgrInterface::QueryInterface(
  1092. REFIID iid,
  1093. void** ppvObject
  1094. )
  1095. {
  1096. BEGIN_EXTERNAL_FUNC
  1097. LogPublicApiBegin( "iid %!guid!, ppvObject %p", &iid, ppvObject );
  1098. HRESULT Hr = S_OK;
  1099. *ppvObject = NULL;
  1100. if ((iid == _uuidof(IUnknown)) || (iid == __uuidof(IBackgroundCopyQMgr)) )
  1101. {
  1102. *ppvObject = (IBackgroundCopyQMgr *)this;
  1103. ((IUnknown *)(*ppvObject))->AddRef();
  1104. }
  1105. else if ( iid == __uuidof(IClassFactory) )
  1106. {
  1107. *ppvObject = (IClassFactory *)this;
  1108. ((IUnknown *)(*ppvObject))->AddRef();
  1109. }
  1110. else
  1111. {
  1112. Hr = E_NOINTERFACE;
  1113. }
  1114. LogPublicApiEnd( "iid %!guid!, ppvObject %p", &iid, ppvObject );
  1115. return Hr;
  1116. END_EXTERNAL_FUNC
  1117. }
  1118. ULONG _stdcall
  1119. COldQmgrInterface::AddRef(void)
  1120. {
  1121. BEGIN_EXTERNAL_FUNC
  1122. ULONG newrefs = InterlockedIncrement(&m_refs);
  1123. LogRef( "new refs = %d", newrefs );
  1124. return newrefs;
  1125. END_EXTERNAL_FUNC
  1126. }
  1127. ULONG _stdcall
  1128. COldQmgrInterface::Release(void)
  1129. {
  1130. BEGIN_EXTERNAL_FUNC
  1131. ULONG newrefs = InterlockedDecrement(&m_refs);
  1132. LogRef( "new refs = %d", newrefs );
  1133. if (newrefs == 0)
  1134. {
  1135. delete this;
  1136. }
  1137. return newrefs;
  1138. END_EXTERNAL_FUNC
  1139. }
  1140. STDMETHODIMP
  1141. COldQmgrInterface::CreateInstance(
  1142. IUnknown * pUnkOuter,
  1143. REFIID riid,
  1144. void ** ppvObject )
  1145. {
  1146. BEGIN_EXTERNAL_FUNC
  1147. HRESULT hr = S_OK;
  1148. if (g_ServiceInstance != m_ServiceInstance ||
  1149. g_ServiceState != MANAGER_ACTIVE)
  1150. {
  1151. hr = CO_E_SERVER_STOPPING;
  1152. }
  1153. else if (pUnkOuter != NULL)
  1154. {
  1155. hr = CLASS_E_NOAGGREGATION;
  1156. }
  1157. else
  1158. {
  1159. if ((riid == IID_IBackgroundCopyQMgr) || (riid == IID_IUnknown))
  1160. {
  1161. hr = QueryInterface(riid, ppvObject);
  1162. }
  1163. else
  1164. {
  1165. //
  1166. // This seems like an odd choice, but we keep it in case some app depends upon it.
  1167. //
  1168. hr = E_OUTOFMEMORY;
  1169. }
  1170. }
  1171. return hr;
  1172. END_EXTERNAL_FUNC
  1173. }
  1174. STDMETHODIMP
  1175. COldQmgrInterface::LockServer(
  1176. BOOL fLock
  1177. )
  1178. {
  1179. BEGIN_EXTERNAL_FUNC
  1180. return GlobalLockServer( fLock );
  1181. END_EXTERNAL_FUNC
  1182. }
  1183. STDMETHODIMP
  1184. COldQmgrInterface::CreateGroupInternal(
  1185. GUID id,
  1186. IBackgroundCopyGroup **ppGroup
  1187. )
  1188. {
  1189. HRESULT Hr = S_OK;
  1190. CLockedJobManagerWritePointer LockedJobManager( m_pJobManager );
  1191. LogPublicApiBegin( "id %!guid!", &id );
  1192. CJob *job = NULL;
  1193. //
  1194. // create the job
  1195. //
  1196. try
  1197. {
  1198. THROW_HRESULT( LockedJobManager.ValidateAccess() );
  1199. ASSERT( ppGroup );
  1200. const WCHAR *DisplayName = L"";
  1201. CLSID *CallbackClass = NULL;
  1202. BG_JOB_TYPE Type = BG_JOB_TYPE_DOWNLOAD;
  1203. THROW_HRESULT( LockedJobManager->CreateJob( DisplayName,
  1204. Type,
  1205. id,
  1206. GetThreadClientSid(),
  1207. &job,
  1208. true
  1209. ));
  1210. THROW_HRESULT( job->SetNotifyFlags( MapOldNotifyToNewNotify(0) ) );
  1211. *ppGroup = ( IBackgroundCopyGroup * )job->GetOldExternalGroupInterface();
  1212. ASSERT( *ppGroup );
  1213. (*ppGroup)->AddRef();
  1214. }
  1215. catch( ComError exception )
  1216. {
  1217. Hr = exception.Error();
  1218. if ( job )
  1219. job->Cancel();
  1220. }
  1221. LogPublicApiEnd( "id %!guid!, group %p", &id, *ppGroup );
  1222. return Hr;
  1223. }
  1224. STDMETHODIMP
  1225. COldQmgrInterface::GetGroupInternal(
  1226. GUID id,
  1227. IBackgroundCopyGroup ** ppGroup
  1228. )
  1229. {
  1230. HRESULT Hr = S_OK;
  1231. CLockedJobManagerWritePointer LockedJobManager( m_pJobManager );
  1232. LogPublicApiBegin( "id %!guid!", &id );
  1233. CJob *pJob = NULL;
  1234. try
  1235. {
  1236. ASSERT( ppGroup );
  1237. *ppGroup = NULL;
  1238. THROW_HRESULT( LockedJobManager.ValidateAccess() );
  1239. Hr = LockedJobManager->GetJob( id, &pJob );
  1240. if (FAILED(Hr))
  1241. {
  1242. if (Hr == BG_E_NOT_FOUND)
  1243. {
  1244. Hr = QM_E_ITEM_NOT_FOUND;
  1245. }
  1246. throw ComError( Hr );
  1247. }
  1248. COldGroupInterface *pOldGroup = pJob->GetOldExternalGroupInterface();
  1249. if ( !pOldGroup )
  1250. throw ComError( QM_E_ITEM_NOT_FOUND );
  1251. // try to take ownership of the job/group
  1252. // this should suceed even if we are the current owner
  1253. THROW_HRESULT( pJob->TakeOwnership());
  1254. pOldGroup->AddRef();
  1255. *ppGroup = (IBackgroundCopyGroup*)pOldGroup;
  1256. }
  1257. catch( ComError Error )
  1258. {
  1259. Hr = Error.Error();
  1260. }
  1261. LogPublicApiEnd( "id %!guid!, group %p", &id, *ppGroup );
  1262. return Hr;
  1263. }
  1264. STDMETHODIMP
  1265. COldQmgrInterface::EnumGroupsInternal(
  1266. DWORD flags,
  1267. IEnumBackgroundCopyGroups **ppEnum
  1268. )
  1269. {
  1270. HRESULT Hr = S_OK;
  1271. CLockedJobManagerWritePointer LockedJobManager( m_pJobManager );
  1272. LogPublicApiBegin( "flags %u, ppEnum %p", flags, ppEnum );
  1273. CEnumOldGroups *pEnum = NULL;
  1274. try
  1275. {
  1276. ASSERT( ppEnum );
  1277. *ppEnum = NULL;
  1278. THROW_HRESULT( LockedJobManager.ValidateAccess() );
  1279. if (flags)
  1280. {
  1281. LogWarning( "rejecting nonzero dwFlags");
  1282. throw ComError( E_NOTIMPL );
  1283. }
  1284. pEnum = new CEnumOldGroups;
  1285. for (CJobList::iterator iter = LockedJobManager->m_OnlineJobs.begin();
  1286. iter != LockedJobManager->m_OnlineJobs.end();
  1287. ++iter)
  1288. {
  1289. Hr = (*iter).IsVisible();
  1290. if (FAILED(Hr))
  1291. {
  1292. throw ComError( Hr );
  1293. }
  1294. if (Hr == S_FALSE)
  1295. {
  1296. continue;
  1297. }
  1298. // Skip jobs that were not created with the old interface.
  1299. if (!(*iter).GetOldExternalGroupInterface())
  1300. {
  1301. continue;
  1302. }
  1303. GUID guid = (*iter).GetId();
  1304. pEnum->Add( guid );
  1305. }
  1306. *ppEnum = pEnum;
  1307. }
  1308. catch( ComError Error )
  1309. {
  1310. Hr = Error.Error();
  1311. delete pEnum;
  1312. }
  1313. LogPublicApiEnd( "flags %u, ppEnum %p", flags, ppEnum );
  1314. return Hr;
  1315. }