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.

609 lines
14 KiB

  1. /************************************************************************
  2. Copyright (c) 2000 - 2000 Microsoft Corporation
  3. Module Name :
  4. cmanager.h
  5. Abstract :
  6. Header file for the CJobManager interface.
  7. Author :
  8. Revision History :
  9. ***********************************************************************/
  10. #pragma once
  11. #include "qmgrlib.h"
  12. #include <list>
  13. #include "clist.h"
  14. #include "logontable.h"
  15. #include "drizcpat.h"
  16. #include "bitstest.h"
  17. #include <map>
  18. using namespace std;
  19. class CJob;
  20. class CJobManagerFactory;
  21. class CJobManager;
  22. class CJobManagerExternal;
  23. class CJobList : public IntrusiveList<CJob>
  24. {
  25. public:
  26. BOOL
  27. Add(
  28. CJob * job
  29. );
  30. CJob *
  31. Find(
  32. REFGUID id
  33. );
  34. BOOL
  35. Remove(
  36. CJob * job
  37. );
  38. ~CJobList();
  39. void Serialize( HANDLE hFile );
  40. void Unserialize( HANDLE hFile );
  41. void Clear();
  42. typedef IntrusiveList<CJob>::iterator iterator;
  43. };
  44. class CJobManagerExternal : public IBackgroundCopyManager,
  45. public IClassFactory,
  46. public IBitsTest1
  47. {
  48. public:
  49. friend CJobManager;
  50. // IUnknown methods
  51. //
  52. STDMETHOD(QueryInterface)(REFIID iid, void** ppvObject);
  53. ULONG __stdcall AddRef(void);
  54. ULONG __stdcall Release(void);
  55. // IBackgroundCopyManager methods
  56. HRESULT STDMETHODCALLTYPE CreateJobInternal(
  57. /* [in] */ LPCWSTR DisplayName,
  58. /* [in] */ BG_JOB_TYPE Type,
  59. /* [out] */ GUID *pJobId,
  60. /* [out] */ IBackgroundCopyJob **ppJob);
  61. HRESULT STDMETHODCALLTYPE CreateJob(
  62. /* [in] */ LPCWSTR DisplayName,
  63. /* [in] */ BG_JOB_TYPE Type,
  64. /* [out] */ GUID *pJobId,
  65. /* [out] */ IBackgroundCopyJob **ppJob)
  66. {
  67. EXTERNAL_FUNC_WRAP( CreateJobInternal( DisplayName, Type, pJobId, ppJob ) )
  68. }
  69. HRESULT STDMETHODCALLTYPE GetJobInternal(
  70. /* [in] */ REFGUID jobID,
  71. /* [out] */ IBackgroundCopyJob **ppJob);
  72. HRESULT STDMETHODCALLTYPE GetJob(
  73. /* [in] */ REFGUID jobID,
  74. /* [out] */ IBackgroundCopyJob **ppJob)
  75. {
  76. EXTERNAL_FUNC_WRAP( GetJobInternal( jobID, ppJob ) )
  77. }
  78. HRESULT STDMETHODCALLTYPE EnumJobsInternal(
  79. /* [in] */ DWORD dwFlags,
  80. /* [out] */ IEnumBackgroundCopyJobs **ppEnum);
  81. HRESULT STDMETHODCALLTYPE EnumJobs(
  82. /* [in] */ DWORD dwFlags,
  83. /* [out] */ IEnumBackgroundCopyJobs **ppEnum)
  84. {
  85. EXTERNAL_FUNC_WRAP( EnumJobsInternal( dwFlags, ppEnum ) )
  86. }
  87. HRESULT STDMETHODCALLTYPE GetErrorDescriptionInternal(
  88. /* [in] */ HRESULT hResult,
  89. /* [in] */ DWORD LanguageId,
  90. /* [out] */ LPWSTR *pErrorDescription );
  91. HRESULT STDMETHODCALLTYPE GetErrorDescription(
  92. /* [in] */ HRESULT hResult,
  93. /* [in] */ DWORD LanguageId,
  94. /* [out] */ LPWSTR *pErrorDescription )
  95. {
  96. EXTERNAL_FUNC_WRAP( GetErrorDescriptionInternal( hResult, LanguageId, pErrorDescription ) )
  97. }
  98. // IClassFactory methods
  99. HRESULT __stdcall CreateInstance(IUnknown* pUnkOuter, REFIID iid, void** ppvObject);
  100. HRESULT __stdcall LockServer(BOOL fLock);
  101. // IBitsTest1 methods
  102. virtual HRESULT STDMETHODCALLTYPE GetBitsDllPath(
  103. /* [out] */ LPWSTR *pVal);
  104. protected:
  105. long m_ServiceInstance;
  106. CJobManager *m_pJobManager;
  107. long m_refs;
  108. CJobManagerExternal();
  109. void SetInterfaceClass(
  110. CJobManager *pVal
  111. )
  112. {
  113. m_pJobManager = pVal;
  114. }
  115. void NotifyInternalDelete()
  116. {
  117. // Release the internal refcount
  118. Release();
  119. }
  120. };
  121. class CDeviceNotificationController
  122. {
  123. public:
  124. virtual ~CDeviceNotificationController();
  125. // General message cracker
  126. DWORD OnDeviceEvent( DWORD dwEventType, LPVOID lpEventData );
  127. // Event methods
  128. virtual void OnDeviceLock( const WCHAR *CanonicalVolume ) = 0;
  129. virtual void OnDeviceUnlock( const WCHAR *CanonicalVolume ) = 0;
  130. virtual void OnDismount( const WCHAR *CanonicalVolume ) = 0;
  131. HRESULT RegisterNotification( const WCHAR *CanonicalVolume );
  132. HRESULT IsVolumeLocked( const WCHAR *CanonicalVolume );
  133. private:
  134. class CDriveNotify
  135. {
  136. public:
  137. HDEVNOTIFY m_hDeviceNotify;
  138. StringHandle m_CanonicalName;
  139. LONG m_LockCount;
  140. LONG m_RemoveCount;
  141. CDriveNotify( HDEVNOTIFY hDeviceNotify,
  142. StringHandle CanonicalName ) :
  143. m_hDeviceNotify( hDeviceNotify ),
  144. m_CanonicalName( CanonicalName ),
  145. m_RemoveCount( 0 ),
  146. m_LockCount( 0 )
  147. {
  148. }
  149. };
  150. typedef map<HDEVNOTIFY, CDriveNotify*> CHandleToNotify;
  151. typedef map<StringHandle, CDriveNotify*> CCanonicalVolumeToNotify;
  152. CHandleToNotify m_HandleToNotify;
  153. CCanonicalVolumeToNotify m_CanonicalVolumeToNotify;
  154. void DeleteNotify( CDriveNotify *pNotify );
  155. };
  156. class CBitsVssWriter : public CVssWriter
  157. /*
  158. CVssWriter is a backup-related class implemented by the system. In October 2002
  159. it was available only on Windows XP and higher. The default implementation does
  160. nothing; BITS ovverrides OnIdentify() to exclude its job temporary and metadata files
  161. from the list to be backed up.
  162. */
  163. {
  164. public:
  165. virtual bool STDMETHODCALLTYPE OnIdentify(IVssCreateWriterMetadata *pMetadata);
  166. //
  167. // Additional vitrual functions required by CVssWriter but not used by our implementation.
  168. //
  169. // callback if current sequence is aborted
  170. virtual bool STDMETHODCALLTYPE OnAbort()
  171. {
  172. return true;
  173. }
  174. // callback for prepare snapsot event
  175. virtual bool STDMETHODCALLTYPE OnPrepareSnapshot()
  176. {
  177. return true;
  178. }
  179. // callback for freeze event
  180. virtual bool STDMETHODCALLTYPE OnFreeze()
  181. {
  182. return true;
  183. }
  184. // callback for thaw event
  185. virtual bool STDMETHODCALLTYPE OnThaw()
  186. {
  187. return true;
  188. }
  189. };
  190. class CJobManager : public TaskSchedulerWorkItem,
  191. private CDeviceNotificationController,
  192. public CQmgrStateFiles
  193. {
  194. public:
  195. friend CJobManagerExternal;
  196. friend COldQmgrInterface;
  197. HRESULT
  198. CreateJob(
  199. LPCWSTR DisplayName,
  200. BG_JOB_TYPE Type,
  201. GUID Id,
  202. SidHandle sid,
  203. CJob ** ppJob,
  204. bool OldStyleJob = false
  205. );
  206. // Returns NULL if job not found
  207. HRESULT GetJob(
  208. REFGUID jobID,
  209. CJob ** ppJob
  210. );
  211. //
  212. // TaskSchedulerWorkItem methods
  213. //
  214. void OnDispatch() { TransferCurrentJob(); }
  215. SidHandle GetSid()
  216. {
  217. return g_GlobalInfo->m_LocalSystemSid;
  218. }
  219. // CDeviceNotificationController methods
  220. DWORD OnDeviceEvent( DWORD dwEventType, LPVOID lpEventData )
  221. {
  222. LockWriter();
  223. DWORD dwResult = CDeviceNotificationController::OnDeviceEvent( dwEventType, lpEventData );
  224. UnlockWriter();
  225. return dwResult;
  226. }
  227. //
  228. // additional functions
  229. //
  230. CJobManager();
  231. virtual ~CJobManager();
  232. //
  233. // Notification that a user has logged on.
  234. //
  235. void SYNCHRONIZED_WRITE
  236. UserLoggedOn(
  237. SidHandle sid
  238. );
  239. //
  240. // Notification that a user has logged off.
  241. //
  242. void SYNCHRONIZED_WRITE
  243. UserLoggedOff(
  244. SidHandle sid
  245. );
  246. //
  247. // Notification that there was a change in the number of active network adapters.
  248. //
  249. void OnNetworkChange();
  250. //
  251. // Called by m_BackupWriter->OnIdentify.
  252. //
  253. bool
  254. OnIdentify(
  255. IN IVssCreateWriterMetadata *pMetadata
  256. );
  257. //
  258. // Adjust the job's online/offline state after its owner changes.
  259. //
  260. void
  261. ResetOnlineStatus(
  262. CJob *pJob,
  263. SidHandle sid
  264. );
  265. void ScheduleDelayedTask(
  266. TaskSchedulerWorkItem * task,
  267. ULONG SecondsOfDelay
  268. )
  269. {
  270. FILETIME TimeToRun = GetTimeAfterDelta( (UINT64) NanoSec100PerSec * SecondsOfDelay );
  271. m_TaskScheduler.InsertWorkItem( task, &TimeToRun );
  272. }
  273. void TaskThread();
  274. HRESULT SuspendJob ( CJob * job );
  275. HRESULT ResumeJob ( CJob * job );
  276. HRESULT CancelJob ( CJob * job );
  277. HRESULT CompleteJob( CJob * job );
  278. HRESULT Serialize();
  279. HRESULT Unserialize();
  280. bool LockReader()
  281. {
  282. return m_TaskScheduler.LockReader();
  283. }
  284. void UnlockReader()
  285. {
  286. m_TaskScheduler.UnlockReader();
  287. }
  288. bool LockWriter()
  289. {
  290. return m_TaskScheduler.LockWriter();
  291. }
  292. void UnlockWriter()
  293. {
  294. m_TaskScheduler.UnlockWriter();
  295. }
  296. //
  297. // recalculates which job should be downloading and kicks the download thread if necessary.
  298. //
  299. void ScheduleAnotherGroup( bool fInsertNetworkDelay = false );
  300. void MoveJobOffline(
  301. CJob * job
  302. );
  303. void AppendOnline(
  304. CJob * job
  305. );
  306. void Shutdown();
  307. HRESULT
  308. CloneUserToken(
  309. SidHandle psid,
  310. DWORD session,
  311. HANDLE * pToken
  312. );
  313. bool IsUserLoggedOn( SidHandle psid );
  314. HRESULT RegisterClassObjects();
  315. void RevokeClassObjects();
  316. HRESULT CreateBackupWriter();
  317. void DeleteBackupWriter();
  318. //--------------------------------------------------------------------
  319. CJobManagerExternal* GetExternalInterface()
  320. {
  321. return m_ExternalInterface;
  322. }
  323. COldQmgrInterface* GetOldExternalInterface()
  324. {
  325. return m_OldQmgrInterface;
  326. }
  327. void NotifyInternalDelete()
  328. {
  329. GetExternalInterface()->NotifyInternalDelete();
  330. }
  331. HRESULT
  332. GetErrorDescription(
  333. HRESULT hResult,
  334. DWORD LanguageId,
  335. LPWSTR *pErrorDescription );
  336. Downloader * m_pPD;
  337. TaskScheduler m_TaskScheduler;
  338. void OnDiskChange( const WCHAR *CanonicalVolume, DWORD VolumeSerialNumber );
  339. HRESULT IsVolumeLocked( const WCHAR *CanonicalPath )
  340. {
  341. return CDeviceNotificationController::IsVolumeLocked( CanonicalPath );
  342. }
  343. void RetaskJob( CJob *pJob );
  344. void InterruptDownload();
  345. void MoveJobToInactiveState( CJob * job );
  346. bool RemoveJob( CJob * job )
  347. {
  348. if (m_OnlineJobs.Remove( job ))
  349. {
  350. return true;
  351. }
  352. if (m_OfflineJobs.Remove( job ))
  353. {
  354. return true;
  355. }
  356. return false;
  357. }
  358. HRESULT CheckClientAccess();
  359. private:
  360. CJob * m_CurrentJob;
  361. HMODULE m_hWininet;
  362. HANDLE m_hQuantumTimer;
  363. // cookies from CoRegisterClassObject.
  364. // used later to unregister.
  365. //
  366. DWORD m_ComId_1_5;
  367. DWORD m_ComId_1_0;
  368. DWORD m_ComId_0_5;
  369. CJobList m_OnlineJobs;
  370. CJobList m_OfflineJobs;
  371. CJobManagerExternal * m_ExternalInterface;
  372. COldQmgrInterface * m_OldQmgrInterface;
  373. public:
  374. CLoggedOnUsers m_Users;
  375. CIpAddressMonitor m_NetworkMonitor;
  376. private:
  377. CBitsVssWriter * m_BackupWriter;
  378. HMODULE m_hVssapi_dll;
  379. //--------------------------------------------------------------------
  380. HRESULT
  381. GetCurrentGroupAndToken(
  382. HANDLE * pToken
  383. );
  384. void TransferCurrentJob();
  385. void ChooseCurrentJob();
  386. void Cleanup();
  387. // Returns the runing or queued jobs that have
  388. // a priority >= current priority.
  389. size_t MoveActiveJobToListEnd( CJob *pJob );
  390. void SetQuantumTimeout();
  391. public:
  392. bool CheckForQuantumTimeout();
  393. void UpdateRemoteSizes(
  394. CUnknownFileSizeList *pUnknownFileSizeList,
  395. HANDLE hToken,
  396. QMErrInfo *pErrorInfo,
  397. const PROXY_SETTINGS * ProxySettings,
  398. const CCredentialsContainer * Credentials
  399. );
  400. private:
  401. // Event methods
  402. void OnDeviceLock( const WCHAR *CanonicalVolume );
  403. void OnDeviceUnlock( const WCHAR *CanonicalVolume );
  404. void OnDismount( const WCHAR *CanonicalVolume );
  405. // methods for dealing with network topology changes
  406. //
  407. static void CALLBACK
  408. NetworkChangeCallback(
  409. PVOID arg
  410. );
  411. void MarkJobsWithNetDisconnected();
  412. void ReactivateTransientErrorJobs();
  413. };
  414. class CLockedJobManagerReadPointer
  415. {
  416. CJobManager * const m_Pointer;
  417. public:
  418. CLockedJobManagerReadPointer( CJobManager * Pointer) :
  419. m_Pointer(Pointer)
  420. { m_Pointer->LockReader(); }
  421. ~CLockedJobManagerReadPointer()
  422. { m_Pointer->UnlockReader(); }
  423. CJobManager * operator->() const { return m_Pointer; }
  424. HRESULT ValidateAccess() { return m_Pointer->CheckClientAccess(); }
  425. };
  426. class CLockedJobManagerWritePointer
  427. {
  428. CJobManager * const m_Pointer;
  429. public:
  430. CLockedJobManagerWritePointer( CJobManager * Pointer) :
  431. m_Pointer(Pointer)
  432. { m_Pointer->LockWriter(); }
  433. ~CLockedJobManagerWritePointer()
  434. { m_Pointer->UnlockWriter(); }
  435. CJobManager * operator->() const { return m_Pointer; }
  436. HRESULT ValidateAccess() { return m_Pointer->CheckClientAccess(); }
  437. };
  438. extern CJobManagerFactory * g_ManagerFactory;
  439. extern CJobManager * g_Manager;
  440. // SENS logon notification
  441. void ActivateSensLogonNotification();
  442. void DeactiveateSensLogonNotification();
  443. extern MANAGER_STATE g_ServiceState;
  444. extern long g_ServiceInstance;
  445. /**
  446. * Checks to see if a given job is being downloaded.
  447. * If so, the constructor interrupts the download, and
  448. * the destructor calls CJobManager::ScheduleAnotherJob().
  449. *
  450. * This is useful for methods that change job properties,
  451. * when those changes affect the download itself.
  452. */
  453. class CRescheduleDownload
  454. {
  455. bool bRunning;
  456. public:
  457. CRescheduleDownload( CJob * job )
  458. {
  459. bRunning = job->IsRunning();
  460. if (bRunning)
  461. {
  462. g_Manager->InterruptDownload();
  463. }
  464. }
  465. ~CRescheduleDownload()
  466. {
  467. if (bRunning)
  468. {
  469. g_Manager->ScheduleAnotherGroup();
  470. }
  471. }
  472. };