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.

1151 lines
30 KiB

  1. /************************************************************************
  2. Copyright (c) 2000 - 2000 Microsoft Corporation
  3. Module Name :
  4. qmgrlib.h
  5. Abstract :
  6. External header for library functions.
  7. Author :
  8. Revision History :
  9. ***********************************************************************/
  10. #pragma once
  11. #include<nt.h>
  12. #include<ntrtl.h>
  13. #include<nturtl.h>
  14. #include <windows.h>
  15. #include <sddl.h>
  16. #include <unknwn.h>
  17. #include <memory>
  18. #include <tchar.h>
  19. #include <strsafe.h>
  20. #include "bitsverp.h"
  21. // strsafe.h deprecates the shlwapi string functions
  22. //
  23. #define NO_SHLWAPI_STRFCNS
  24. //
  25. // Version Control
  26. //
  27. enum PLATFORM_PRODUCT_VERSION
  28. {
  29. WIN95_PLATFORM,
  30. WIN98_PLATFORM,
  31. #if defined( BITS_V12_ON_NT4 )
  32. NT4_PLATFORM,
  33. #endif
  34. WINDOWS2000_PLATFORM,
  35. WINDOWSXP_PLATFORM
  36. };
  37. extern PLATFORM_PRODUCT_VERSION g_PlatformVersion;
  38. extern DWORD g_PlatformMajorVersion;
  39. extern DWORD g_PlatformMinorVersion;
  40. extern bool bIsWin9x;
  41. extern HINSTANCE g_hInstance;
  42. BOOL DetectProductVersion();
  43. //
  44. // Limits
  45. //
  46. const size_t INT_DIGITS = 10;
  47. const size_t INT64_DIGITS = 20;
  48. const SIZE_T MAX_DISPLAYNAME = 255;
  49. const SIZE_T MAX_DESCRIPTION = 1023;
  50. const SIZE_T MAX_PROXYLIST = 32767;
  51. const SIZE_T MAX_PROXYBYPASSLIST = 32767;
  52. const SIZE_T MAX_NOTIFY_PROGRAM = MAX_PATH;
  53. const SIZE_T MAX_NOTIFY_PARAMETERS = 4000;
  54. const SIZE_T MAX_SESSION_ID = 100;
  55. const SIZE_T MAX_HOST_ID = 300; // allow room for a full DNS name
  56. const SIZE_T MAX_PACKET_TYPE = 40; // maximum length of Bits-Packet-Type header
  57. const SIZE_T MAX_USERNAME = 300;
  58. const SIZE_T MAX_PASSWORD = 300;
  59. //
  60. // Metadata overhead
  61. //
  62. const SIZE_T METADATA_PADDING = 4096; // Padding on metadata for small changes such as timers
  63. const SIZE_T METADATA_PREALLOC_SIZE = 262144; // Size to prealloc before a change
  64. const SIZE_T METADATA_FOR_FILE = 4096; // Initial file size.
  65. const UINT MAX_GUID_CHARS=40;
  66. typedef WCHAR GUIDSTR[MAX_GUID_CHARS];
  67. template <class T>
  68. inline void SafeRelease( T * & p ) { if (NULL != (p)) { p->Release(); p = NULL; } }
  69. //
  70. // Metadata internal file marker GUIDs
  71. //
  72. // {2B196AF5-007C-438f-8D12-1CFCA4CC9B76}
  73. const GUID QmgrStateStorageGUID =
  74. { 0x2b196af5, 0x7c, 0x438f, { 0x8d, 0x12, 0x1c, 0xfc, 0xa4, 0xcc, 0x9b, 0x76 } };
  75. // {005F4447-BDA9-44ba-9851-C47BB6C07ACE}
  76. const GUID GroupListStorageGUID =
  77. { 0x5f4447, 0xbda9, 0x44ba, { 0x98, 0x51, 0xc4, 0x7b, 0xb6, 0xc0, 0x7a, 0xce } };
  78. // {C82BF713-9940-4a12-9F1A-3AAEBD894EEA}
  79. const GUID PriorityQueuesStorageGUID =
  80. { 0xc82bf713, 0x9940, 0x4a12, { 0x9f, 0x1a, 0x3a, 0xae, 0xbd, 0x89, 0x4e, 0xea } };
  81. //
  82. // The standard error class. This is the only type of C++ exception that
  83. // BITS functions should throw.
  84. //
  85. class ComError
  86. {
  87. public:
  88. HRESULT m_error;
  89. unsigned m_line;
  90. ComError(HRESULT NewErrorCode) : m_error ( NewErrorCode ), m_line(0) {}
  91. ComError(HRESULT NewErrorCode, unsigned line) : m_error ( NewErrorCode ), m_line(line) {}
  92. HRESULT Error() { return m_error; }
  93. };
  94. #define THROW_HRESULT( _expr_ ) \
  95. { \
  96. HRESULT _hr_ = _expr_; \
  97. if (FAILED(_hr_)) \
  98. { \
  99. throw ComError( _hr_, __LINE__ ); \
  100. } \
  101. }
  102. #define ThrowLastError() throw ComError( HRESULT_FROM_WIN32( GetLastError() ), __LINE__)
  103. using namespace std;
  104. template<HANDLE InvalidValue=NULL>
  105. class auto_HANDLE
  106. {
  107. public:
  108. auto_HANDLE(HANDLE Handle = InvalidValue)
  109. : m_Handle(Handle) {}
  110. auto_HANDLE(auto_HANDLE<InvalidValue>& Other)
  111. : m_Handle(Other.release()) {}
  112. auto_HANDLE<InvalidValue>& operator=( HANDLE Handle )
  113. {
  114. if (InvalidValue != m_Handle)
  115. {
  116. CloseHandle(m_Handle);
  117. }
  118. m_Handle = Handle;
  119. return *this;
  120. }
  121. auto_HANDLE<InvalidValue>& operator=(auto_HANDLE<InvalidValue>& Other)
  122. {
  123. if (this != &Other)
  124. {
  125. m_Handle = Other.release();
  126. }
  127. return *this;
  128. }
  129. ~auto_HANDLE()
  130. {
  131. if (InvalidValue != m_Handle)
  132. CloseHandle(m_Handle);
  133. }
  134. HANDLE get() const
  135. {
  136. return m_Handle;
  137. }
  138. HANDLE * GetWritePointer()
  139. {
  140. return &m_Handle;
  141. }
  142. HANDLE release()
  143. {
  144. HANDLE Handle = m_Handle;
  145. m_Handle = InvalidValue;
  146. return Handle;
  147. }
  148. private:
  149. HANDLE m_Handle;
  150. };
  151. typedef auto_HANDLE<INVALID_HANDLE_VALUE> auto_FILE_HANDLE;
  152. class SidHandle
  153. {
  154. PSID m_pValue;
  155. long * m_pRefs;
  156. public:
  157. PSID operator->() { ASSERT( *m_pRefs > 0); return m_pValue; }
  158. SidHandle( PSID value=NULL ) : m_pValue( value ), m_pRefs( new long(1) )
  159. {
  160. }
  161. SidHandle( const SidHandle & r ) : m_pValue( r.m_pValue ), m_pRefs( r.m_pRefs )
  162. {
  163. InterlockedIncrement( m_pRefs );
  164. }
  165. ~SidHandle()
  166. {
  167. if ( InterlockedDecrement( m_pRefs ) == 0 )
  168. {
  169. delete m_pRefs;
  170. delete m_pValue;
  171. m_pRefs = NULL;
  172. m_pValue = NULL;
  173. }
  174. }
  175. SidHandle & operator=( const SidHandle & r );
  176. bool operator==( const SidHandle & r ) const
  177. {
  178. // this odd construction converts BOOL to bool.
  179. //
  180. return !!EqualSid( get(), r.get());
  181. }
  182. bool operator!=( const SidHandle & r ) const
  183. {
  184. return !((*this) == r);
  185. }
  186. PSID get() const { ASSERT( *m_pRefs > 0); return m_pValue; }
  187. };
  188. template<class T>
  189. class GenericStringHandle
  190. {
  191. struct StringData
  192. {
  193. SIZE_T m_Count;
  194. long m_Refs;
  195. T m_Data[1];
  196. };
  197. static StringData s_EmptyString;
  198. StringData *m_Value;
  199. void NewString( const T *String )
  200. {
  201. if ( !String )
  202. {
  203. m_Value = Alloc( 0 );
  204. return;
  205. }
  206. size_t Length = wcslen( String );
  207. m_Value = Alloc( Length );
  208. THROW_HRESULT( StringCchCopy( m_Value->m_Data, Length+1, String ));
  209. }
  210. static StringData * Alloc( SIZE_T max )
  211. {
  212. if (max == 0)
  213. {
  214. InterlockedIncrement( &s_EmptyString.m_Refs );
  215. return &s_EmptyString;
  216. }
  217. StringData * Value;
  218. Value = (StringData*) new char[sizeof(StringData)+(max*sizeof(T))];
  219. Value->m_Count = max;
  220. Value->m_Refs = 1;
  221. Value->m_Data[0] = L'\0';
  222. return Value;
  223. }
  224. StringData * RefIt() const
  225. {
  226. InterlockedIncrement( &m_Value->m_Refs );
  227. return m_Value;
  228. }
  229. void FreeIt()
  230. {
  231. if ( m_Value->m_Refs && InterlockedDecrement( &m_Value->m_Refs ) == 0 )
  232. {
  233. delete m_Value;
  234. m_Value = NULL;
  235. }
  236. }
  237. public:
  238. GenericStringHandle( const T *String = NULL )
  239. {
  240. NewString( String );
  241. }
  242. GenericStringHandle( const GenericStringHandle & Other ) :
  243. m_Value( Other.RefIt() )
  244. {
  245. }
  246. ~GenericStringHandle()
  247. {
  248. FreeIt();
  249. }
  250. GenericStringHandle & operator=( const GenericStringHandle & r )
  251. {
  252. FreeIt();
  253. m_Value = r.RefIt();
  254. return *this;
  255. }
  256. void operator=( const T * r )
  257. {
  258. FreeIt();
  259. NewString( r );
  260. }
  261. SIZE_T Size() const
  262. {
  263. return m_Value->m_Count;
  264. }
  265. operator const T *() const
  266. {
  267. return m_Value->m_Data;
  268. }
  269. //
  270. // Force a new copy of the data to be made.
  271. //
  272. GenericStringHandle Copy()
  273. {
  274. GenericStringHandle temp = m_Value->m_Data;
  275. return temp;
  276. }
  277. bool operator <( const GenericStringHandle & r ) const
  278. {
  279. if ( m_Value == r.m_Value)
  280. return false;
  281. return (wcscmp( this->m_Value->m_Data, r.m_Value->m_Data ) < 0);
  282. }
  283. T & operator[] ( const SIZE_T offset )
  284. {
  285. if (offset > Size())
  286. {
  287. THROW_HRESULT( E_INVALIDARG );
  288. }
  289. return m_Value->m_Data[ offset ];
  290. }
  291. void Truncate( SIZE_T max )
  292. {
  293. if (Size() <= max)
  294. {
  295. return;
  296. }
  297. //
  298. // Create the new value string.
  299. //
  300. StringData * NewValue = Alloc( max );
  301. StringCchCopy( NewValue->m_Data, max+1, m_Value->m_Data );
  302. //
  303. // Replace the current value with the new value.
  304. //
  305. FreeIt();
  306. m_Value = NewValue;
  307. }
  308. T * GetToken( T * CursorIn, const T Separators[], T ** CursorOut );
  309. };
  310. typedef GenericStringHandle<TCHAR> StringHandleT;
  311. typedef GenericStringHandle<CHAR> StringHandleA;
  312. typedef GenericStringHandle<WCHAR> StringHandle;
  313. inline WCHAR *
  314. GenericStringHandle<WCHAR>::GetToken( WCHAR * Cursor, const WCHAR Separators[], WCHAR **pCursor )
  315. {
  316. if (Cursor == NULL)
  317. {
  318. Cursor = m_Value->m_Data;
  319. }
  320. WCHAR * Token = NULL;
  321. if (Cursor < m_Value->m_Data + m_Value->m_Count)
  322. {
  323. Token = wcstok( Cursor, Separators );
  324. }
  325. if (Token)
  326. {
  327. *pCursor = Token + wcslen(Token) + 1;
  328. }
  329. else
  330. {
  331. *pCursor = m_Value->m_Data + m_Value->m_Count;
  332. }
  333. return Token;
  334. }
  335. typedef auto_ptr<WCHAR> CAutoStringW;
  336. typedef auto_ptr<TCHAR> CAutoStringT;
  337. typedef auto_ptr<char> CAutoStringA;
  338. typedef CAutoStringW CAutoString;
  339. //
  340. // PSID does not have an obvious ordering of the type required by the MAP classes.
  341. // So we define one here.
  342. //
  343. class CSidSorter
  344. {
  345. public:
  346. bool operator()( const SidHandle & psid1, const SidHandle & psid2 ) const;
  347. };
  348. PSID DuplicateSid( PSID _Sid );
  349. //---------------------------------------------
  350. enum FILE_DOWNLOAD_RESULT
  351. {
  352. QM_IN_PROGRESS,
  353. QM_FILE_ABORTED,
  354. QM_FILE_DONE,
  355. QM_FILE_TRANSIENT_ERROR,
  356. QM_FILE_FATAL_ERROR,
  357. QM_SERVER_FILE_CHANGED
  358. };
  359. /*
  360. The source field is divided into regions, like NTSTATUS and HRESULT codes.
  361. The lowest-order bit is bit 0; the highest is bit 31.
  362. bit 31: reserved, MBZ
  363. bits 30-29: component
  364. 00 = unknown
  365. 01 = queue manager
  366. 10 = transport
  367. 11 =
  368. bits 28-16: sub-component
  369. for queue manager: 0 = unknown
  370. 1 = local file handling
  371. 2 = queue management
  372. 3 = notification
  373. for transport: 0 = unknown
  374. 1 = HTTP
  375. 2 = HTTPS
  376. 3 = FTP
  377. 4 = SMB
  378. 5 = DAV
  379. bits 15-0: defined by sub-component
  380. for HTTP: 0 = unknown
  381. 1 = client connection
  382. 2 = server connection
  383. 3 = server file handling
  384. */
  385. #define COMPONENT_MASK (0x3 << 30)
  386. #define SUBCOMP_MASK (0x3fff << 16)
  387. #define FINAL_MASK (0xffff << 0 )
  388. #define COMPONENT_QMGR (0x1 << 30)
  389. #define COMPONENT_TRANS (0x2 << 30)
  390. #define SUBCOMP_QMGR_FILE (0x1 << 16)
  391. #define SUBCOMP_QMGR_QUEUE (0x2 << 16)
  392. #define SUBCOMP_QMGR_NOTIFY (0x3 << 16)
  393. #define SUBCOMP_QMGR_CACHE (0x4 << 16)
  394. #define SUBCOMP_TRANS_HTTP (COMPONENT_TRANS | (0x1 << 16))
  395. #define SUBCOMP_TRANS_HTTPS (COMPONENT_TRANS | (0x2 << 16))
  396. #define SUBCOMP_TRANS_FTP (COMPONENT_TRANS | (0x3 << 16))
  397. enum ERROR_SOURCE
  398. {
  399. SOURCE_NONE = 0,
  400. SOURCE_QMGR_FILE = (COMPONENT_QMGR | SUBCOMP_QMGR_FILE | 0x0),
  401. SOURCE_QMGR_QUEUE = (COMPONENT_QMGR | SUBCOMP_QMGR_QUEUE | 0x0),
  402. SOURCE_QMGR_NOTIFY = (COMPONENT_QMGR | SUBCOMP_QMGR_NOTIFY | 0x0),
  403. SOURCE_HTTP_UNKNOWN = (COMPONENT_TRANS | SUBCOMP_TRANS_HTTP | 0x0),
  404. SOURCE_HTTP_CLIENT_CONN = (COMPONENT_TRANS | SUBCOMP_TRANS_HTTP | 0x1),
  405. SOURCE_HTTP_SERVER = (COMPONENT_TRANS | SUBCOMP_TRANS_HTTP | 0x2),
  406. SOURCE_HTTP_SERVER_FILE = (COMPONENT_TRANS | SUBCOMP_TRANS_HTTP | 0x3),
  407. SOURCE_HTTP_SERVER_APP = (COMPONENT_TRANS | SUBCOMP_TRANS_HTTP | 0x4)
  408. };
  409. enum ERROR_STYLE
  410. {
  411. ERROR_STYLE_NONE = 0,
  412. ERROR_STYLE_HRESULT = 1,
  413. ERROR_STYLE_WIN32 = 2,
  414. ERROR_STYLE_HTTP = 3
  415. };
  416. struct QMErrInfo
  417. {
  418. FILE_DOWNLOAD_RESULT result;
  419. UINT64 Code;
  420. ERROR_STYLE Style;
  421. ERROR_SOURCE Source;
  422. wchar_t * Description;
  423. QMErrInfo()
  424. {
  425. result = QM_FILE_DONE;
  426. Clear();
  427. }
  428. QMErrInfo(
  429. ERROR_SOURCE Source,
  430. ERROR_STYLE Style,
  431. UINT64 Code,
  432. char * comment = 0
  433. );
  434. QMErrInfo(
  435. FILE_DOWNLOAD_RESULT Result,
  436. ERROR_SOURCE Source,
  437. ERROR_STYLE Style,
  438. UINT64 Code,
  439. char * comment = 0
  440. ) : result( Result ), Description( NULL )
  441. {
  442. Set( Source, Style, Code, comment );
  443. }
  444. void
  445. Set(
  446. ERROR_SOURCE Source,
  447. ERROR_STYLE Style,
  448. UINT64 Code,
  449. char * comment = 0
  450. );
  451. void Clear()
  452. {
  453. Source = SOURCE_NONE;
  454. Style = ERROR_STYLE_NONE;
  455. Code = 0;
  456. Description = NULL;
  457. }
  458. bool IsSet()
  459. {
  460. return (Style != ERROR_STYLE_NONE);
  461. }
  462. void Log();
  463. bool operator==( const QMErrInfo & err )
  464. {
  465. if (Source == err.Source &&
  466. Style == err.Style &&
  467. Code == err.Code)
  468. {
  469. return true;
  470. }
  471. return false;
  472. }
  473. bool operator!=( const QMErrInfo & err )
  474. {
  475. if (*this == err)
  476. {
  477. return false;
  478. }
  479. return true;
  480. }
  481. };
  482. //---------------------------------------------
  483. const UINT64 NanoSec100PerSec = 10000000; //no of 100 nanosecs per sec
  484. const TCHAR * const C_BITS_USER_AGENT = _T("Microsoft BITS/") VER_PRODUCTVERSION_WSTRING;
  485. // Registry keys
  486. const TCHAR * const C_QMGR_REG_KEY = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\BITS");
  487. // Registry Value(REG_SZ).
  488. // Point to where to load the upgraded DLL
  489. const TCHAR * const C_QMGR_SERVICEDLL = _T("ServiceDLL");
  490. // Registry Values(REG_DWORD/seconds)
  491. const TCHAR * const C_QMGR_STATE_INDEX = _T("StateIndex");
  492. const TCHAR * const C_QMGR_JOB_INACTIVITY_TIMEOUT = _T("JobInactivityTimeout");
  493. const TCHAR * const C_QMGR_TIME_QUANTA_LENGTH = _T("TimeQuantaLength");
  494. const TCHAR * const C_QMGR_NO_PROGRESS_TIMEOUT = _T("JobNoProgressTimeout");
  495. const TCHAR * const C_QMGR_MINIMUM_RETRY_DELAY = _T("JobMinimumRetryDelay");
  496. const TCHAR * const C_QMGR_ALLOW_TEST_DLL = _T("AllowTestDll");
  497. // Logging registry Values(REG_DWORD)
  498. const TCHAR * const C_QMGR_LOGFILE_SIZE = _T("LogFileSize"); // In MB
  499. const TCHAR * const C_QMGR_LOGFILE_FLAGS = _T("LogFileFlags");
  500. const TCHAR * const C_QMGR_LOGFILE_MINMEMORY = _T("LogFileMinMemory"); // In MB
  501. // default values
  502. const UINT32 C_QMGR_JOB_INACTIVITY_TIMEOUT_DEFAULT = (60ui64 * 60ui64 * 24ui64 * 90ui64); // 90 days
  503. const UINT32 C_QMGR_TIME_QUANTA_LENGTH_DEFAULT = (5 * 60); // 5 minutes
  504. const UINT32 C_QMGR_NO_PROGRESS_TIMEOUT_DEFAULT = (14 * 24 * 60 * 60); //14 days
  505. const UINT32 C_QMGR_MINIMUM_RETRY_DELAY_DEFAULT = (10 * 60); // ten minutes
  506. // Logging default values
  507. const UINT32 C_QMGR_LOGFILE_SIZE_DEFAULT = 1;
  508. #if DBG
  509. // Debug/Non-ship mode
  510. // everything except 0x010 - Ref Counts and 0x020 - State File
  511. //
  512. const UINT32 C_QMGR_LOGFILE_FLAGS_DEFAULT = 0xFFCF;
  513. #else
  514. const UINT32 C_QMGR_LOGFILE_FLAGS_DEFAULT = 0;
  515. #endif
  516. const UINT32 C_QMGR_LOGFILE_MINMEMORY_DEFAULT = 120;
  517. // Policy keys
  518. const TCHAR * const C_QMGR_POLICY_REG_KEY = _T("Software\\Policies\\Microsoft\\Windows\\BITS");
  519. // Policy values
  520. const TCHAR * const C_QMGR_POLICY_JOB_INACTIVITY_TIMEOUT = _T("JobInactivityTimeout");
  521. //
  522. // The directory "%ALLUSERSPROFILE%\Application Data\Microsoft" should always exist.
  523. // At startup, we create "Microsoft\Network" and "Microsoft\Network\Downloader" if necessary.
  524. // To avoid having to parse and verify the whole path, the last two components are explicitly checked.
  525. //
  526. const TCHAR * const C_QMGR_PARENT_DIRECTORY = _T("\\Microsoft\\Network\\");
  527. const TCHAR * const C_QMGR_DIRECTORY = _T("\\Microsoft\\Network\\Downloader\\");
  528. const wchar_t NullString[] = L"(null)";
  529. // cfreg.cpp - Functions to handle registry keys
  530. HRESULT GetRegStringValue(LPCTSTR lpszValueName, LPTSTR lpszBuffer, int iBufferSize);
  531. HRESULT SetRegStringValue(LPCTSTR lpszValueName, LPCTSTR lpszNewValue);
  532. HRESULT DeleteRegStringValue(LPCTSTR lpszValueName);
  533. HRESULT GetRegDWordValue(LPCTSTR lpszValueName, LPDWORD pdwValue);
  534. HRESULT SetRegDWordValue(LPCTSTR lpszValueName, DWORD dwValue);
  535. // service.cxx
  536. HRESULT SetServiceStartup( bool bAutoStart );
  537. // helpers.cpp
  538. BOOL QMgrFileExists(LPCTSTR szFile);
  539. FILETIME GetTimeAfterDelta( UINT64 uDelta );
  540. BOOL IsConnected();
  541. LPCWSTR TruncateString( LPCWSTR String, SIZE_T MaxLength, auto_ptr<WCHAR> & AutoPointer );
  542. ////////////////////////////////////////////////////////////////////////
  543. //
  544. // Global info class
  545. //
  546. ////////////////////////////////////////////////////////////////////////
  547. class GlobalInfo
  548. {
  549. private:
  550. GlobalInfo( TCHAR *QmgrDirectory,
  551. LARGE_INTEGER PerfamceCounterFrequency,
  552. HKEY QmgrRegistryRoot,
  553. UINT64 JobInactivityTimeout,
  554. UINT64 TimeQuantaLength,
  555. UINT32 DefaultNoProgressTimeout,
  556. UINT32 DefaultMinimumRetryDelay,
  557. SECURITY_DESCRIPTOR *MetadataSecurityDescriptor,
  558. DWORD MetadataSecurityDescriptorLength,
  559. SidHandle AdministratorsSid,
  560. SidHandle LocalSystemSid,
  561. SidHandle NetworkUsersSid,
  562. SidHandle AnonymousSid
  563. );
  564. ~GlobalInfo();
  565. public:
  566. static DWORD RegGetDWORD( HKEY hKey, const TCHAR * pValue, DWORD dwDefault );
  567. const TCHAR * const m_QmgrDirectory;
  568. const LARGE_INTEGER m_PerformanceCounterFrequency;
  569. const HKEY m_QmgrRegistryRoot;
  570. const UINT64 m_JobInactivityTimeout;
  571. const UINT64 m_TimeQuantaLength;
  572. const UINT32 m_DefaultNoProgressTimeout;
  573. const UINT32 m_DefaultMinimumRetryDelay;
  574. const SECURITY_DESCRIPTOR * const m_MetadataSecurityDescriptor;
  575. const DWORD m_MetadataSecurityDescriptorLength;
  576. const SidHandle m_AdministratorsSid;
  577. const SidHandle m_LocalSystemSid;
  578. const SidHandle m_NetworkUsersSid;
  579. const SidHandle m_AnonymousSid;
  580. static HRESULT Init(void);
  581. static HRESULT Uninit(void);
  582. };
  583. extern class GlobalInfo *g_GlobalInfo;
  584. //
  585. // variables to keep track of service state
  586. //
  587. enum MANAGER_STATE
  588. {
  589. MANAGER_INACTIVE,
  590. MANAGER_STARTING,
  591. MANAGER_ACTIVE,
  592. MANAGER_TERMINATING
  593. };
  594. extern MANAGER_STATE g_ServiceState;
  595. extern long g_ServiceInstance;
  596. extern DWORD g_LastServiceControl;
  597. //
  598. // Jump to a label on failure. Assumes an HRESULT "hr" and a label "Cleanup".
  599. //
  600. #define CLEANUP_ON_FAILURE( x ) \
  601. hr = x; \
  602. if (FAILED(hr)) \
  603. { \
  604. goto Cleanup; \
  605. }
  606. #define RETURN_HRESULT( x ) \
  607. { \
  608. HRESULT _hr_ = (x); \
  609. if (FAILED(_hr_)) \
  610. { \
  611. return _hr_; \
  612. } \
  613. }
  614. #define GFA_FAILED DWORD(-1)
  615. inline BOOL FileExists( LPWSTR szFile )
  616. {
  617. DWORD dwAttr = GetFileAttributes( szFile );
  618. if( GFA_FAILED == dwAttr )
  619. return FALSE;
  620. return (BOOL)( !(dwAttr & FILE_ATTRIBUTE_DIRECTORY) );
  621. }
  622. inline UINT64 FILETIMEToUINT64( const FILETIME & FileTime )
  623. {
  624. ULARGE_INTEGER LargeInteger;
  625. LargeInteger.HighPart = FileTime.dwHighDateTime;
  626. LargeInteger.LowPart = FileTime.dwLowDateTime;
  627. return LargeInteger.QuadPart;
  628. }
  629. inline FILETIME UINT64ToFILETIME( UINT64 Int64Value )
  630. {
  631. ULARGE_INTEGER LargeInteger;
  632. LargeInteger.QuadPart = Int64Value;
  633. FILETIME FileTime;
  634. FileTime.dwHighDateTime = LargeInteger.HighPart;
  635. FileTime.dwLowDateTime = LargeInteger.LowPart;
  636. return FileTime;
  637. }
  638. //------------------------------------------------------------------------
  639. //
  640. // NT security
  641. //
  642. //------------------------------------------------------------------------
  643. SidHandle GetThreadClientSid();
  644. HRESULT
  645. ImpersonateSid(
  646. PSID sid
  647. );
  648. BOOL
  649. SidToString(
  650. PSID sid,
  651. wchar_t buffer[],
  652. USHORT bytes
  653. );
  654. HRESULT
  655. IsRemoteUser();
  656. HRESULT
  657. IsAdministratorUser();
  658. HRESULT
  659. DenyRemoteAccess();
  660. HRESULT
  661. DenyNonAdminAccess();
  662. PSID DuplicateSid( PSID _Sid );
  663. //
  664. // allows CreateInstanceInSession to choose an arbitrary session.
  665. //
  666. #define ANY_SESSION DWORD(-1)
  667. HRESULT
  668. CreateInstanceInSession(
  669. REFCLSID clsid,
  670. REFIID iid,
  671. DWORD session,
  672. void ** pif
  673. );
  674. HRESULT
  675. SetStaticCloaking(
  676. IUnknown *pUnk
  677. );
  678. HRESULT
  679. ApplyIdentityToInterface(
  680. IUnknown *pUnk,
  681. PSID sid
  682. );
  683. struct IBackgroundCopyCallback;
  684. struct IBackgroundCopyCallback1;
  685. HRESULT
  686. CreateUserCallback(
  687. CLSID clsid,
  688. PSID sid,
  689. IBackgroundCopyCallback **pICB
  690. );
  691. HRESULT
  692. CreateOldUserCallback(
  693. CLSID clsid,
  694. PSID sid,
  695. IBackgroundCopyCallback1 **pICB
  696. );
  697. HRESULT
  698. SessionLogonCallback(
  699. DWORD SessionId
  700. );
  701. HRESULT
  702. SessionLogoffCallback(
  703. DWORD SessionId
  704. );
  705. DWORD
  706. DeviceEventCallback(
  707. DWORD dwEventType,
  708. LPVOID lpEventData
  709. );
  710. BOOL Log_Init();
  711. void Log_StartLogger();
  712. void Log_Close();
  713. HRESULT GlobalInit();
  714. HRESULT GlobalUninit();
  715. HRESULT InitQmgr();
  716. HRESULT UninitQmgr();
  717. const GUID BITSCtrlGuid = {0x4a8aaa94,0xcfc4,0x46a7,{0x8e,0x4e,0x17,0xbc,0x45,0x60,0x8f,0x0a}};
  718. #define WPP_CONTROL_GUIDS \
  719. WPP_DEFINE_CONTROL_GUID(CtlGuid,(4a8aaa94,cfc4,46a7,8e4e,17bc45608f0a), \
  720. WPP_DEFINE_BIT(LogFlagInfo) \
  721. WPP_DEFINE_BIT(LogFlagWarning) \
  722. WPP_DEFINE_BIT(LogFlagError) \
  723. WPP_DEFINE_BIT(LogFlagFunction) \
  724. WPP_DEFINE_BIT(LogFlagRefCount) \
  725. WPP_DEFINE_BIT(LogFlagSerialize) \
  726. WPP_DEFINE_BIT(LogFlagDownload) \
  727. WPP_DEFINE_BIT(LogFlagTask) \
  728. WPP_DEFINE_BIT(LogFlagLock) \
  729. WPP_DEFINE_BIT(LogFlagService) \
  730. )
  731. #define LogLevelEnabled(flags) WPP_LEVEL_ENABLED(flags) \
  732. LONG ExternalFuncExceptionFilter( struct _EXCEPTION_POINTERS *ExceptionInfo );
  733. //
  734. // We keep track of COM calls because we can't delete our objects at shutdown
  735. // until all the active calls have stopped referring to them.
  736. //
  737. extern long g_cCalls;
  738. inline void IncrementCallCount()
  739. {
  740. InterlockedIncrement(&g_cCalls);
  741. }
  742. inline void DecrementCallCount()
  743. {
  744. InterlockedDecrement(&g_cCalls);
  745. }
  746. inline long ActiveCallCount()
  747. {
  748. return g_cCalls;
  749. }
  750. //
  751. // A simple helper class to keep track of our call count.
  752. //
  753. class DispatchedCall
  754. {
  755. public:
  756. DispatchedCall() { IncrementCallCount(); }
  757. ~DispatchedCall() { DecrementCallCount(); }
  758. };
  759. //
  760. // Each member function of our public COM interfaces has an external
  761. // and an internal version. The external version is simply
  762. // {
  763. // EXTERNAL_FUNC_WRAP( internal-version );
  764. // }
  765. // This captures any exceptions in a way that can be reported by the OfficeWatson
  766. // error-reporting apparatus.
  767. // It also checks for service shutdown.
  768. //
  769. HRESULT
  770. CheckServerInstance(
  771. long ObjectServiceInstance
  772. );
  773. #define EXTERNAL_FUNC_WRAP( call_parent ) \
  774. \
  775. __try \
  776. { \
  777. RETURN_HRESULT( CheckServerInstance( m_ServiceInstance )); \
  778. \
  779. HRESULT hr = call_parent ; \
  780. \
  781. DecrementCallCount(); \
  782. return hr; \
  783. } \
  784. __except( ExternalFuncExceptionFilter( GetExceptionInformation() ) ) \
  785. { \
  786. DecrementCallCount(); \
  787. return RPC_E_SERVERFAULT; \
  788. } \
  789. //
  790. // IUnknown member functions use these alternate macros.
  791. //
  792. #define BEGIN_EXTERNAL_FUNC \
  793. __try \
  794. { \
  795. #define END_EXTERNAL_FUNC \
  796. } \
  797. __except( ExternalFuncExceptionFilter( GetExceptionInformation() ) ) \
  798. { \
  799. return RPC_E_SERVERFAULT; \
  800. } \
  801. StringHandle
  802. BITSCrackFileName(
  803. const WCHAR * RawFileName,
  804. StringHandle & ReturnFileName
  805. );
  806. StringHandle
  807. BITSCreateTempFile(
  808. StringHandle Directory
  809. );
  810. HRESULT
  811. BITSCheckFileWritability(
  812. LPCWSTR name
  813. );
  814. StringHandle
  815. CombineUrl(
  816. LPCWSTR BaseUrl,
  817. LPCWSTR RelativeUrl,
  818. DWORD Flags
  819. );
  820. LPWSTR MidlCopyString( LPCWSTR source, size_t Length = -1);
  821. inline LPWSTR MidlCopyString( StringHandle source )
  822. {
  823. return MidlCopyString( source, source.Size()+1 );
  824. }
  825. LPWSTR CopyString( LPCWSTR source, size_t Length = -1);
  826. inline LPWSTR CopyString( StringHandle source )
  827. {
  828. return CopyString( source, source.Size()+1 );
  829. }
  830. inline bool operator==( const FILETIME left, const FILETIME right )
  831. {
  832. return ((left.dwLowDateTime == right.dwLowDateTime) &&
  833. (left.dwHighDateTime == right.dwHighDateTime));
  834. }
  835. inline bool operator!=( const FILETIME left, const FILETIME right )
  836. {
  837. return !(left == right);
  838. }
  839. bool IsServiceShuttingDown();
  840. bool IsAnyDebuggerPresent();
  841. bool InitCompilerLibrary();
  842. bool UninitCompilerLibrary();
  843. #if defined(BITS_V12_ON_NT4)
  844. extern ULONG BITSFlags;
  845. void Log( const CHAR *Prefix, const CHAR *Format, va_list ArgList );
  846. const DWORD LogFlagInfo = 0;
  847. const DWORD LogFlagWarning = 1;
  848. const DWORD LogFlagError = 2;
  849. const DWORD LogFlagFunction = 4;
  850. const DWORD LogFlagRefCount = 8;
  851. const DWORD LogFlagRef = LogFlagRefCount;
  852. const DWORD LogFlagSerialize = 16;
  853. const DWORD LogFlagSerial = LogFlagSerialize;
  854. const DWORD LogFlagDownload = 32;
  855. const DWORD LogFlagDl = LogFlagDownload;
  856. const DWORD LogFlagTask = 64;
  857. const DWORD LogFlagLock = 128;
  858. const DWORD LogFlagService = 256;
  859. const DWORD LogFlagPublicApiBegin = LogFlagFunction;
  860. const DWORD LogFlagPublicApiEnd = LogFlagFunction;
  861. #define DEFINE_SIMPLE_LOG_FUNCT( flag, prefix ) \
  862. inline void Log##flag##( const char *format, ...) \
  863. { \
  864. if ( ! ( BITSFlags & ~LogFlag##flag ) ) \
  865. return; \
  866. va_list marker; \
  867. va_start( marker, format ); \
  868. Log( prefix, format, marker ); \
  869. } \
  870. DEFINE_SIMPLE_LOG_FUNCT( Info, " INFO :" )
  871. DEFINE_SIMPLE_LOG_FUNCT( Warning, " WARNING :" )
  872. DEFINE_SIMPLE_LOG_FUNCT( Error, " ERROR :" )
  873. DEFINE_SIMPLE_LOG_FUNCT( PublicApiBegin, " FUNC_BEGIN :" )
  874. DEFINE_SIMPLE_LOG_FUNCT( PublicApiEnd, " FUNC_END :" )
  875. DEFINE_SIMPLE_LOG_FUNCT( Ref, " REF :" )
  876. DEFINE_SIMPLE_LOG_FUNCT( Lock, " LOCK :" )
  877. DEFINE_SIMPLE_LOG_FUNCT( Task, " TASK :" )
  878. DEFINE_SIMPLE_LOG_FUNCT( Service, " SERVICE :" )
  879. DEFINE_SIMPLE_LOG_FUNCT( Dl, " DOWNLOAD :" )
  880. DEFINE_SIMPLE_LOG_FUNCT( Serial, " SERIALIZE :" )
  881. BOOL
  882. BITSAltGetFileSizeEx(
  883. HANDLE hFile, // handle to file
  884. PLARGE_INTEGER lpFileSize // file size
  885. );
  886. BOOL
  887. BITSAltSetFilePointerEx(
  888. HANDLE hFile, // handle to file
  889. LARGE_INTEGER liDistanceToMove, // bytes to move pointer
  890. PLARGE_INTEGER lpNewFilePointer, // new file pointer
  891. DWORD dwMoveMethod // starting point
  892. );
  893. BOOL
  894. BITSAltConvertSidToStringSidW(
  895. IN PSID Sid,
  896. OUT LPWSTR *StringSid
  897. );
  898. BOOL
  899. BITSAltConvertStringSidToSidW(
  900. IN LPCWSTR StringSid,
  901. OUT PSID *Sid
  902. );
  903. BOOL
  904. BITSAltCheckTokenMembership(
  905. IN HANDLE TokenHandle OPTIONAL,
  906. IN PSID SidToCheck,
  907. OUT PBOOL IsMember
  908. );
  909. SERVICE_STATUS_HANDLE
  910. BITSAltRegisterServiceCtrlHandlerExW(
  911. LPCTSTR lpServiceName, // name of service
  912. LPHANDLER_FUNCTION_EX lpHandlerProc, // handler function
  913. LPVOID lpContext // user data
  914. );
  915. #define GetFileSizeEx BITSAltGetFileSizeEx
  916. #define SetFilePointerEx BITSAltSetFilePointerEx
  917. #define ConvertSidToStringSidW BITSAltConvertSidToStringSidW
  918. #define ConvertStringSidToSidW BITSAltConvertStringSidToSidW
  919. #define CheckTokenMembership BITSAltCheckTokenMembership
  920. #define RegisterServiceCtrlHandlerExW BITSAltRegisterServiceCtrlHandlerExW
  921. #endif