Source code of Windows XP (NT5)
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.

535 lines
12 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. #if !defined( BITS_V12_ON_NT4 )
  122. class CDeviceNotificationController
  123. {
  124. public:
  125. virtual ~CDeviceNotificationController();
  126. // General message cracker
  127. DWORD OnDeviceEvent( DWORD dwEventType, LPVOID lpEventData );
  128. // Event methods
  129. virtual void OnDeviceLock( const WCHAR *CanonicalVolume ) = 0;
  130. virtual void OnDeviceUnlock( const WCHAR *CanonicalVolume ) = 0;
  131. virtual void OnDismount( const WCHAR *CanonicalVolume ) = 0;
  132. HRESULT RegisterNotification( const WCHAR *CanonicalVolume );
  133. HRESULT IsVolumeLocked( const WCHAR *CanonicalVolume );
  134. private:
  135. class CDriveNotify
  136. {
  137. public:
  138. HDEVNOTIFY m_hDeviceNotify;
  139. StringHandle m_CanonicalName;
  140. LONG m_LockCount;
  141. CDriveNotify( HDEVNOTIFY hDeviceNotify,
  142. StringHandle CanonicalName ) :
  143. m_hDeviceNotify( hDeviceNotify ),
  144. m_CanonicalName( CanonicalName ),
  145. m_LockCount( 0 )
  146. {
  147. }
  148. };
  149. typedef map<HDEVNOTIFY, CDriveNotify*> CHandleToNotify;
  150. typedef map<StringHandle, CDriveNotify*> CCanonicalVolumeToNotify;
  151. CHandleToNotify m_HandleToNotify;
  152. CCanonicalVolumeToNotify m_CanonicalVolumeToNotify;
  153. void DeleteNotify( CDriveNotify *pNotify );
  154. };
  155. #endif
  156. class CJobManager : public TaskSchedulerWorkItem,
  157. #if !defined( BITS_V12_ON_NT4 )
  158. private CDeviceNotificationController,
  159. #endif
  160. public CQmgrStateFiles
  161. {
  162. public:
  163. friend CJobManagerExternal;
  164. friend COldQmgrInterface;
  165. HRESULT
  166. CreateJob(
  167. LPCWSTR DisplayName,
  168. BG_JOB_TYPE Type,
  169. GUID Id,
  170. SidHandle sid,
  171. CJob ** ppJob,
  172. bool OldStyleJob = false
  173. );
  174. // Returns NULL if job not found
  175. HRESULT GetJob(
  176. REFGUID jobID,
  177. CJob ** ppJob
  178. );
  179. //
  180. // TaskSchedulerWorkItem methods
  181. //
  182. void OnDispatch() { TransferCurrentJob(); }
  183. SidHandle GetSid()
  184. {
  185. return g_GlobalInfo->m_LocalSystemSid;
  186. }
  187. #if !defined( BITS_V12_ON_NT4 )
  188. // CDeviceNotificationController methods
  189. DWORD OnDeviceEvent( DWORD dwEventType, LPVOID lpEventData )
  190. {
  191. LockWriter();
  192. DWORD dwResult = CDeviceNotificationController::OnDeviceEvent( dwEventType, lpEventData );
  193. UnlockWriter();
  194. return dwResult;
  195. }
  196. #endif
  197. //
  198. // additional functions
  199. //
  200. CJobManager();
  201. virtual ~CJobManager();
  202. //
  203. // Notification that a user has logged on.
  204. //
  205. void SYNCHRONIZED_WRITE
  206. UserLoggedOn(
  207. SidHandle sid
  208. );
  209. //
  210. // Notification that a user has logged off.
  211. //
  212. void SYNCHRONIZED_WRITE
  213. UserLoggedOff(
  214. SidHandle sid
  215. );
  216. //
  217. // Notification that there was a change in the number of active network adapters.
  218. //
  219. void OnNetworkChange();
  220. //
  221. // Adjust the job's online/offline state after its owner changes.
  222. //
  223. void
  224. ResetOnlineStatus(
  225. CJob *pJob,
  226. SidHandle sid
  227. );
  228. void ScheduleDelayedTask(
  229. TaskSchedulerWorkItem * task,
  230. ULONG SecondsOfDelay
  231. )
  232. {
  233. FILETIME TimeToRun = GetTimeAfterDelta( (UINT64) NanoSec100PerSec * SecondsOfDelay );
  234. m_TaskScheduler.InsertWorkItem( task, &TimeToRun );
  235. }
  236. void TaskThread();
  237. HRESULT SuspendJob ( CJob * job );
  238. HRESULT ResumeJob ( CJob * job );
  239. HRESULT CancelJob ( CJob * job );
  240. HRESULT CompleteJob( CJob * job );
  241. HRESULT Serialize();
  242. HRESULT Unserialize();
  243. bool LockReader()
  244. {
  245. return m_TaskScheduler.LockReader();
  246. }
  247. void UnlockReader()
  248. {
  249. m_TaskScheduler.UnlockReader();
  250. }
  251. bool LockWriter()
  252. {
  253. return m_TaskScheduler.LockWriter();
  254. }
  255. void UnlockWriter()
  256. {
  257. m_TaskScheduler.UnlockWriter();
  258. }
  259. //
  260. // recalculates which job should be downloading and kicks the download thread if necessary.
  261. //
  262. void ScheduleAnotherGroup( bool fInsertNetworkDelay = false );
  263. void MoveJobOffline(
  264. CJob * job
  265. );
  266. void AppendOnline(
  267. CJob * job
  268. );
  269. void Shutdown();
  270. HRESULT
  271. CloneUserToken(
  272. SidHandle psid,
  273. DWORD session,
  274. HANDLE * pToken
  275. );
  276. bool IsUserLoggedOn( SidHandle psid );
  277. HRESULT RegisterClassObjects();
  278. void RevokeClassObjects();
  279. //--------------------------------------------------------------------
  280. CJobManagerExternal* GetExternalInterface()
  281. {
  282. return m_ExternalInterface;
  283. }
  284. COldQmgrInterface* GetOldExternalInterface()
  285. {
  286. return m_OldQmgrInterface;
  287. }
  288. void NotifyInternalDelete()
  289. {
  290. GetExternalInterface()->NotifyInternalDelete();
  291. }
  292. HRESULT
  293. GetErrorDescription(
  294. HRESULT hResult,
  295. DWORD LanguageId,
  296. LPWSTR *pErrorDescription );
  297. Downloader * m_pPD;
  298. TaskScheduler m_TaskScheduler;
  299. void OnDiskChange( const WCHAR *CanonicalVolume, DWORD VolumeSerialNumber );
  300. #if !defined( BITS_V12_ON_NT4 )
  301. HRESULT IsVolumeLocked( const WCHAR *CanonicalPath )
  302. {
  303. return CDeviceNotificationController::IsVolumeLocked( CanonicalPath );
  304. }
  305. #endif
  306. void RetaskJob( CJob *pJob );
  307. void InterruptDownload();
  308. void MoveJobToInactiveState( CJob * job );
  309. bool RemoveJob( CJob * job )
  310. {
  311. if (m_OnlineJobs.Remove( job ))
  312. {
  313. return true;
  314. }
  315. if (m_OfflineJobs.Remove( job ))
  316. {
  317. return true;
  318. }
  319. return false;
  320. }
  321. private:
  322. CJob * m_CurrentJob;
  323. HMODULE m_hWininet;
  324. HANDLE m_hQuantumTimer;
  325. // cookies from CoRegisterClassObject.
  326. // used later to unregister.
  327. //
  328. DWORD m_ComId_1_5;
  329. DWORD m_ComId_1_0;
  330. DWORD m_ComId_0_5;
  331. CJobList m_OnlineJobs;
  332. CJobList m_OfflineJobs;
  333. CJobManagerExternal * m_ExternalInterface;
  334. COldQmgrInterface * m_OldQmgrInterface;
  335. public:
  336. CLoggedOnUsers m_Users;
  337. #if !defined( BITS_V12_ON_NT4 )
  338. CIpAddressMonitor m_NetworkMonitor;
  339. #endif
  340. private:
  341. //--------------------------------------------------------------------
  342. HRESULT
  343. GetCurrentGroupAndToken(
  344. HANDLE * pToken
  345. );
  346. void TransferCurrentJob();
  347. void ChooseCurrentJob();
  348. void Cleanup();
  349. // Returns the runing or queued jobs that have
  350. // a priority >= current priority.
  351. size_t MoveActiveJobToListEnd( CJob *pJob );
  352. void SetQuantumTimeout();
  353. public:
  354. bool CheckForQuantumTimeout();
  355. void UpdateRemoteSizes(
  356. CUnknownFileSizeList *pUnknownFileSizeList,
  357. HANDLE hToken,
  358. QMErrInfo *pErrorInfo,
  359. const PROXY_SETTINGS * ProxySettings,
  360. const CCredentialsContainer * Credentials
  361. );
  362. private:
  363. // Event methods
  364. void OnDeviceLock( const WCHAR *CanonicalVolume );
  365. void OnDeviceUnlock( const WCHAR *CanonicalVolume );
  366. void OnDismount( const WCHAR *CanonicalVolume );
  367. // methods for dealing with network topology changes
  368. //
  369. static void CALLBACK
  370. NetworkChangeCallback(
  371. PVOID arg
  372. );
  373. void MarkJobsWithNetDisconnected();
  374. void ReactivateTransientErrorJobs();
  375. };
  376. class CLockedJobManagerReadPointer
  377. {
  378. CJobManager * const m_Pointer;
  379. public:
  380. CLockedJobManagerReadPointer( CJobManager * Pointer) :
  381. m_Pointer(Pointer)
  382. { m_Pointer->LockReader(); }
  383. ~CLockedJobManagerReadPointer()
  384. { m_Pointer->UnlockReader(); }
  385. CJobManager * operator->() const { return m_Pointer; }
  386. HRESULT ValidateAccess() { return DenyRemoteAccess(); }
  387. };
  388. class CLockedJobManagerWritePointer
  389. {
  390. CJobManager * const m_Pointer;
  391. public:
  392. CLockedJobManagerWritePointer( CJobManager * Pointer) :
  393. m_Pointer(Pointer)
  394. { m_Pointer->LockWriter(); }
  395. ~CLockedJobManagerWritePointer()
  396. { m_Pointer->UnlockWriter(); }
  397. CJobManager * operator->() const { return m_Pointer; }
  398. HRESULT ValidateAccess() { return DenyRemoteAccess(); }
  399. };
  400. extern CJobManagerFactory * g_ManagerFactory;
  401. extern CJobManager * g_Manager;
  402. // SENS logon notification
  403. void ActivateSensLogonNotification();
  404. void DeactiveateSensLogonNotification();
  405. extern MANAGER_STATE g_ServiceState;
  406. extern long g_ServiceInstance;