|
|
/************************************************************************
Copyright (c) 2000 - 2000 Microsoft Corporation
Module Name :
qmgrlib.h
Abstract :
External header for library functions.
Author :
Revision History :
***********************************************************************/
#pragma once
#include<nt.h>
#include<ntrtl.h>
#include<nturtl.h>
#include <windows.h>
#include <sddl.h>
#include <unknwn.h>
#include <memory>
#include <tchar.h>
#include <strsafe.h>
#include "bitsverp.h"
// strsafe.h deprecates the shlwapi string functions
//
#define NO_SHLWAPI_STRFCNS
//
// Version Control
//
enum PLATFORM_PRODUCT_VERSION { WIN95_PLATFORM, WIN98_PLATFORM, #if defined( BITS_V12_ON_NT4 )
NT4_PLATFORM, #endif
WINDOWS2000_PLATFORM, WINDOWSXP_PLATFORM };
extern PLATFORM_PRODUCT_VERSION g_PlatformVersion; extern DWORD g_PlatformMajorVersion; extern DWORD g_PlatformMinorVersion; extern bool bIsWin9x;
extern HINSTANCE g_hInstance;
BOOL DetectProductVersion();
//
// Limits
//
const size_t INT_DIGITS = 10; const size_t INT64_DIGITS = 20;
const SIZE_T MAX_DISPLAYNAME = 255; const SIZE_T MAX_DESCRIPTION = 1023; const SIZE_T MAX_PROXYLIST = 32767; const SIZE_T MAX_PROXYBYPASSLIST = 32767; const SIZE_T MAX_NOTIFY_PROGRAM = MAX_PATH; const SIZE_T MAX_NOTIFY_PARAMETERS = 4000; const SIZE_T MAX_SESSION_ID = 100; const SIZE_T MAX_HOST_ID = 300; // allow room for a full DNS name
const SIZE_T MAX_PACKET_TYPE = 40; // maximum length of Bits-Packet-Type header
const SIZE_T MAX_USERNAME = 300; const SIZE_T MAX_PASSWORD = 300;
//
// Metadata overhead
//
const SIZE_T METADATA_PADDING = 4096; // Padding on metadata for small changes such as timers
const SIZE_T METADATA_PREALLOC_SIZE = 262144; // Size to prealloc before a change
const SIZE_T METADATA_FOR_FILE = 4096; // Initial file size.
const UINT MAX_GUID_CHARS=40; typedef WCHAR GUIDSTR[MAX_GUID_CHARS];
template <class T> inline void SafeRelease( T * & p ) { if (NULL != (p)) { p->Release(); p = NULL; } }
//
// Metadata internal file marker GUIDs
//
// {2B196AF5-007C-438f-8D12-1CFCA4CC9B76}
const GUID QmgrStateStorageGUID = { 0x2b196af5, 0x7c, 0x438f, { 0x8d, 0x12, 0x1c, 0xfc, 0xa4, 0xcc, 0x9b, 0x76 } };
// {005F4447-BDA9-44ba-9851-C47BB6C07ACE}
const GUID GroupListStorageGUID = { 0x5f4447, 0xbda9, 0x44ba, { 0x98, 0x51, 0xc4, 0x7b, 0xb6, 0xc0, 0x7a, 0xce } };
// {C82BF713-9940-4a12-9F1A-3AAEBD894EEA}
const GUID PriorityQueuesStorageGUID = { 0xc82bf713, 0x9940, 0x4a12, { 0x9f, 0x1a, 0x3a, 0xae, 0xbd, 0x89, 0x4e, 0xea } };
//
// The standard error class. This is the only type of C++ exception that
// BITS functions should throw.
//
class ComError { public:
HRESULT m_error; unsigned m_line;
ComError(HRESULT NewErrorCode) : m_error ( NewErrorCode ), m_line(0) {} ComError(HRESULT NewErrorCode, unsigned line) : m_error ( NewErrorCode ), m_line(line) {}
HRESULT Error() { return m_error; }
};
#define THROW_HRESULT( _expr_ ) \
{ \ HRESULT _hr_ = _expr_; \ if (FAILED(_hr_)) \ { \ throw ComError( _hr_, __LINE__ ); \ } \ }
#define ThrowLastError() throw ComError( HRESULT_FROM_WIN32( GetLastError() ), __LINE__)
using namespace std;
template<HANDLE InvalidValue=NULL> class auto_HANDLE { public: auto_HANDLE(HANDLE Handle = InvalidValue) : m_Handle(Handle) {} auto_HANDLE(auto_HANDLE<InvalidValue>& Other) : m_Handle(Other.release()) {} auto_HANDLE<InvalidValue>& operator=( HANDLE Handle ) { if (InvalidValue != m_Handle) { CloseHandle(m_Handle); } m_Handle = Handle; return *this; } auto_HANDLE<InvalidValue>& operator=(auto_HANDLE<InvalidValue>& Other) { if (this != &Other) { m_Handle = Other.release(); } return *this; } ~auto_HANDLE() { if (InvalidValue != m_Handle) CloseHandle(m_Handle); } HANDLE get() const { return m_Handle; }
HANDLE * GetWritePointer() { return &m_Handle; }
HANDLE release() { HANDLE Handle = m_Handle; m_Handle = InvalidValue; return Handle; } private: HANDLE m_Handle; }; typedef auto_HANDLE<INVALID_HANDLE_VALUE> auto_FILE_HANDLE;
class SidHandle { PSID m_pValue; long * m_pRefs;
public:
PSID operator->() { ASSERT( *m_pRefs > 0); return m_pValue; }
SidHandle( PSID value=NULL ) : m_pValue( value ), m_pRefs( new long(1) ) { }
SidHandle( const SidHandle & r ) : m_pValue( r.m_pValue ), m_pRefs( r.m_pRefs ) { InterlockedIncrement( m_pRefs ); }
~SidHandle() { if ( InterlockedDecrement( m_pRefs ) == 0 ) { delete m_pRefs; delete m_pValue; m_pRefs = NULL; m_pValue = NULL; } }
SidHandle & operator=( const SidHandle & r );
bool operator==( const SidHandle & r ) const { // this odd construction converts BOOL to bool.
//
return !!EqualSid( get(), r.get()); }
bool operator!=( const SidHandle & r ) const { return !((*this) == r); }
PSID get() const { ASSERT( *m_pRefs > 0); return m_pValue; }
};
template<class T> class GenericStringHandle {
struct StringData { SIZE_T m_Count; long m_Refs; T m_Data[1]; };
static StringData s_EmptyString;
StringData *m_Value;
void NewString( const T *String ) { if ( !String ) { m_Value = Alloc( 0 ); return; }
size_t Length = wcslen( String ); m_Value = Alloc( Length );
THROW_HRESULT( StringCchCopy( m_Value->m_Data, Length+1, String )); }
static StringData * Alloc( SIZE_T max ) { if (max == 0) { InterlockedIncrement( &s_EmptyString.m_Refs ); return &s_EmptyString; }
StringData * Value;
Value = (StringData*) new char[sizeof(StringData)+(max*sizeof(T))]; Value->m_Count = max; Value->m_Refs = 1;
Value->m_Data[0] = L'\0';
return Value; }
StringData * RefIt() const { InterlockedIncrement( &m_Value->m_Refs ); return m_Value; }
void FreeIt() { if ( m_Value->m_Refs && InterlockedDecrement( &m_Value->m_Refs ) == 0 ) { delete m_Value; m_Value = NULL; } }
public:
GenericStringHandle( const T *String = NULL ) { NewString( String ); }
GenericStringHandle( const GenericStringHandle & Other ) : m_Value( Other.RefIt() ) { }
~GenericStringHandle() { FreeIt(); }
GenericStringHandle & operator=( const GenericStringHandle & r ) { FreeIt(); m_Value = r.RefIt(); return *this; }
void operator=( const T * r ) { FreeIt(); NewString( r ); }
SIZE_T Size() const { return m_Value->m_Count; }
operator const T *() const { return m_Value->m_Data; }
//
// Force a new copy of the data to be made.
//
GenericStringHandle Copy() { GenericStringHandle temp = m_Value->m_Data; return temp; }
bool operator <( const GenericStringHandle & r ) const { if ( m_Value == r.m_Value) return false; return (wcscmp( this->m_Value->m_Data, r.m_Value->m_Data ) < 0); }
T & operator[] ( const SIZE_T offset ) { if (offset > Size()) { THROW_HRESULT( E_INVALIDARG ); }
return m_Value->m_Data[ offset ]; }
void Truncate( SIZE_T max ) { if (Size() <= max) { return; }
//
// Create the new value string.
//
StringData * NewValue = Alloc( max );
StringCchCopy( NewValue->m_Data, max+1, m_Value->m_Data );
//
// Replace the current value with the new value.
//
FreeIt(); m_Value = NewValue; }
T * GetToken( T * CursorIn, const T Separators[], T ** CursorOut ); };
typedef GenericStringHandle<TCHAR> StringHandleT; typedef GenericStringHandle<CHAR> StringHandleA; typedef GenericStringHandle<WCHAR> StringHandle;
inline WCHAR * GenericStringHandle<WCHAR>::GetToken( WCHAR * Cursor, const WCHAR Separators[], WCHAR **pCursor ) { if (Cursor == NULL) { Cursor = m_Value->m_Data; }
WCHAR * Token = NULL;
if (Cursor < m_Value->m_Data + m_Value->m_Count) { Token = wcstok( Cursor, Separators ); }
if (Token) { *pCursor = Token + wcslen(Token) + 1; } else { *pCursor = m_Value->m_Data + m_Value->m_Count; }
return Token; }
typedef auto_ptr<WCHAR> CAutoStringW; typedef auto_ptr<TCHAR> CAutoStringT; typedef auto_ptr<char> CAutoStringA; typedef CAutoStringW CAutoString;
//
// PSID does not have an obvious ordering of the type required by the MAP classes.
// So we define one here.
//
class CSidSorter { public:
bool operator()( const SidHandle & psid1, const SidHandle & psid2 ) const; };
PSID DuplicateSid( PSID _Sid );
//---------------------------------------------
enum FILE_DOWNLOAD_RESULT { QM_IN_PROGRESS, QM_FILE_ABORTED, QM_FILE_DONE, QM_FILE_TRANSIENT_ERROR, QM_FILE_FATAL_ERROR, QM_SERVER_FILE_CHANGED }; /*
The source field is divided into regions, like NTSTATUS and HRESULT codes. The lowest-order bit is bit 0; the highest is bit 31.
bit 31: reserved, MBZ
bits 30-29: component
00 = unknown 01 = queue manager 10 = transport 11 =
bits 28-16: sub-component
for queue manager: 0 = unknown 1 = local file handling 2 = queue management 3 = notification
for transport: 0 = unknown 1 = HTTP 2 = HTTPS 3 = FTP 4 = SMB 5 = DAV
bits 15-0: defined by sub-component
for HTTP: 0 = unknown 1 = client connection 2 = server connection 3 = server file handling
*/
#define COMPONENT_MASK (0x3 << 30)
#define SUBCOMP_MASK (0x3fff << 16)
#define FINAL_MASK (0xffff << 0 )
#define COMPONENT_QMGR (0x1 << 30)
#define COMPONENT_TRANS (0x2 << 30)
#define SUBCOMP_QMGR_FILE (0x1 << 16)
#define SUBCOMP_QMGR_QUEUE (0x2 << 16)
#define SUBCOMP_QMGR_NOTIFY (0x3 << 16)
#define SUBCOMP_QMGR_CACHE (0x4 << 16)
#define SUBCOMP_TRANS_HTTP (COMPONENT_TRANS | (0x1 << 16))
#define SUBCOMP_TRANS_HTTPS (COMPONENT_TRANS | (0x2 << 16))
#define SUBCOMP_TRANS_FTP (COMPONENT_TRANS | (0x3 << 16))
enum ERROR_SOURCE { SOURCE_NONE = 0, SOURCE_QMGR_FILE = (COMPONENT_QMGR | SUBCOMP_QMGR_FILE | 0x0), SOURCE_QMGR_QUEUE = (COMPONENT_QMGR | SUBCOMP_QMGR_QUEUE | 0x0), SOURCE_QMGR_NOTIFY = (COMPONENT_QMGR | SUBCOMP_QMGR_NOTIFY | 0x0),
SOURCE_HTTP_UNKNOWN = (COMPONENT_TRANS | SUBCOMP_TRANS_HTTP | 0x0), SOURCE_HTTP_CLIENT_CONN = (COMPONENT_TRANS | SUBCOMP_TRANS_HTTP | 0x1), SOURCE_HTTP_SERVER = (COMPONENT_TRANS | SUBCOMP_TRANS_HTTP | 0x2), SOURCE_HTTP_SERVER_FILE = (COMPONENT_TRANS | SUBCOMP_TRANS_HTTP | 0x3), SOURCE_HTTP_SERVER_APP = (COMPONENT_TRANS | SUBCOMP_TRANS_HTTP | 0x4) };
enum ERROR_STYLE { ERROR_STYLE_NONE = 0, ERROR_STYLE_HRESULT = 1, ERROR_STYLE_WIN32 = 2, ERROR_STYLE_HTTP = 3 };
struct QMErrInfo { FILE_DOWNLOAD_RESULT result;
UINT64 Code; ERROR_STYLE Style; ERROR_SOURCE Source; wchar_t * Description;
QMErrInfo() { result = QM_FILE_DONE; Clear(); }
QMErrInfo( ERROR_SOURCE Source, ERROR_STYLE Style, UINT64 Code, char * comment = 0 );
QMErrInfo( FILE_DOWNLOAD_RESULT Result, ERROR_SOURCE Source, ERROR_STYLE Style, UINT64 Code, char * comment = 0 ) : result( Result ), Description( NULL ) { Set( Source, Style, Code, comment ); }
void Set( ERROR_SOURCE Source, ERROR_STYLE Style, UINT64 Code, char * comment = 0 );
void Clear() { Source = SOURCE_NONE; Style = ERROR_STYLE_NONE; Code = 0; Description = NULL; }
bool IsSet() { return (Style != ERROR_STYLE_NONE); }
void Log();
bool operator==( const QMErrInfo & err ) { if (Source == err.Source && Style == err.Style && Code == err.Code) { return true; }
return false; }
bool operator!=( const QMErrInfo & err ) { if (*this == err) { return false; }
return true; } };
//---------------------------------------------
const UINT64 NanoSec100PerSec = 10000000; //no of 100 nanosecs per sec
const TCHAR * const C_BITS_USER_AGENT = _T("Microsoft BITS/") VER_PRODUCTVERSION_WSTRING;
// Registry keys
const TCHAR * const C_QMGR_REG_KEY = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\BITS");
// Registry Value(REG_SZ).
// Point to where to load the upgraded DLL
const TCHAR * const C_QMGR_SERVICEDLL = _T("ServiceDLL");
// Registry Values(REG_DWORD/seconds)
const TCHAR * const C_QMGR_STATE_INDEX = _T("StateIndex"); const TCHAR * const C_QMGR_JOB_INACTIVITY_TIMEOUT = _T("JobInactivityTimeout"); const TCHAR * const C_QMGR_TIME_QUANTA_LENGTH = _T("TimeQuantaLength"); const TCHAR * const C_QMGR_NO_PROGRESS_TIMEOUT = _T("JobNoProgressTimeout"); const TCHAR * const C_QMGR_MINIMUM_RETRY_DELAY = _T("JobMinimumRetryDelay"); const TCHAR * const C_QMGR_ALLOW_TEST_DLL = _T("AllowTestDll");
// Logging registry Values(REG_DWORD)
const TCHAR * const C_QMGR_LOGFILE_SIZE = _T("LogFileSize"); // In MB
const TCHAR * const C_QMGR_LOGFILE_FLAGS = _T("LogFileFlags"); const TCHAR * const C_QMGR_LOGFILE_MINMEMORY = _T("LogFileMinMemory"); // In MB
// default values
const UINT32 C_QMGR_JOB_INACTIVITY_TIMEOUT_DEFAULT = (60ui64 * 60ui64 * 24ui64 * 90ui64); // 90 days
const UINT32 C_QMGR_TIME_QUANTA_LENGTH_DEFAULT = (5 * 60); // 5 minutes
const UINT32 C_QMGR_NO_PROGRESS_TIMEOUT_DEFAULT = (14 * 24 * 60 * 60); //14 days
const UINT32 C_QMGR_MINIMUM_RETRY_DELAY_DEFAULT = (10 * 60); // ten minutes
// Logging default values
const UINT32 C_QMGR_LOGFILE_SIZE_DEFAULT = 1;
#if DBG
// Debug/Non-ship mode
// everything except 0x010 - Ref Counts and 0x020 - State File
//
const UINT32 C_QMGR_LOGFILE_FLAGS_DEFAULT = 0xFFCF; #else
const UINT32 C_QMGR_LOGFILE_FLAGS_DEFAULT = 0; #endif
const UINT32 C_QMGR_LOGFILE_MINMEMORY_DEFAULT = 120;
// Policy keys
const TCHAR * const C_QMGR_POLICY_REG_KEY = _T("Software\\Policies\\Microsoft\\Windows\\BITS");
// Policy values
const TCHAR * const C_QMGR_POLICY_JOB_INACTIVITY_TIMEOUT = _T("JobInactivityTimeout");
//
// The directory "%ALLUSERSPROFILE%\Application Data\Microsoft" should always exist.
// At startup, we create "Microsoft\Network" and "Microsoft\Network\Downloader" if necessary.
// To avoid having to parse and verify the whole path, the last two components are explicitly checked.
//
const TCHAR * const C_QMGR_PARENT_DIRECTORY = _T("\\Microsoft\\Network\\"); const TCHAR * const C_QMGR_DIRECTORY = _T("\\Microsoft\\Network\\Downloader\\");
const wchar_t NullString[] = L"(null)";
// cfreg.cpp - Functions to handle registry keys
HRESULT GetRegStringValue(LPCTSTR lpszValueName, LPTSTR lpszBuffer, int iBufferSize); HRESULT SetRegStringValue(LPCTSTR lpszValueName, LPCTSTR lpszNewValue); HRESULT DeleteRegStringValue(LPCTSTR lpszValueName); HRESULT GetRegDWordValue(LPCTSTR lpszValueName, LPDWORD pdwValue); HRESULT SetRegDWordValue(LPCTSTR lpszValueName, DWORD dwValue);
// service.cxx
HRESULT SetServiceStartup( bool bAutoStart );
// helpers.cpp
BOOL QMgrFileExists(LPCTSTR szFile); FILETIME GetTimeAfterDelta( UINT64 uDelta ); BOOL IsConnected();
LPCWSTR TruncateString( LPCWSTR String, SIZE_T MaxLength, auto_ptr<WCHAR> & AutoPointer );
////////////////////////////////////////////////////////////////////////
//
// Global info class
//
////////////////////////////////////////////////////////////////////////
class GlobalInfo { private:
GlobalInfo( TCHAR *QmgrDirectory, LARGE_INTEGER PerfamceCounterFrequency, HKEY QmgrRegistryRoot, UINT64 JobInactivityTimeout, UINT64 TimeQuantaLength, UINT32 DefaultNoProgressTimeout, UINT32 DefaultMinimumRetryDelay, SECURITY_DESCRIPTOR *MetadataSecurityDescriptor, DWORD MetadataSecurityDescriptorLength, SidHandle AdministratorsSid, SidHandle LocalSystemSid, SidHandle NetworkUsersSid, SidHandle AnonymousSid );
~GlobalInfo();
public:
static DWORD RegGetDWORD( HKEY hKey, const TCHAR * pValue, DWORD dwDefault );
const TCHAR * const m_QmgrDirectory; const LARGE_INTEGER m_PerformanceCounterFrequency; const HKEY m_QmgrRegistryRoot; const UINT64 m_JobInactivityTimeout; const UINT64 m_TimeQuantaLength; const UINT32 m_DefaultNoProgressTimeout; const UINT32 m_DefaultMinimumRetryDelay; const SECURITY_DESCRIPTOR * const m_MetadataSecurityDescriptor; const DWORD m_MetadataSecurityDescriptorLength; const SidHandle m_AdministratorsSid; const SidHandle m_LocalSystemSid; const SidHandle m_NetworkUsersSid; const SidHandle m_AnonymousSid;
static HRESULT Init(void); static HRESULT Uninit(void);
};
extern class GlobalInfo *g_GlobalInfo;
//
// variables to keep track of service state
//
enum MANAGER_STATE { MANAGER_INACTIVE, MANAGER_STARTING, MANAGER_ACTIVE, MANAGER_TERMINATING };
extern MANAGER_STATE g_ServiceState; extern long g_ServiceInstance; extern DWORD g_LastServiceControl;
//
// Jump to a label on failure. Assumes an HRESULT "hr" and a label "Cleanup".
//
#define CLEANUP_ON_FAILURE( x ) \
hr = x; \ if (FAILED(hr)) \ { \ goto Cleanup; \ }
#define RETURN_HRESULT( x ) \
{ \ HRESULT _hr_ = (x); \ if (FAILED(_hr_)) \ { \ return _hr_; \ } \ }
#define GFA_FAILED DWORD(-1)
inline BOOL FileExists( LPWSTR szFile ) { DWORD dwAttr = GetFileAttributes( szFile );
if( GFA_FAILED == dwAttr ) return FALSE;
return (BOOL)( !(dwAttr & FILE_ATTRIBUTE_DIRECTORY) ); }
inline UINT64 FILETIMEToUINT64( const FILETIME & FileTime ) { ULARGE_INTEGER LargeInteger; LargeInteger.HighPart = FileTime.dwHighDateTime; LargeInteger.LowPart = FileTime.dwLowDateTime; return LargeInteger.QuadPart; }
inline FILETIME UINT64ToFILETIME( UINT64 Int64Value ) { ULARGE_INTEGER LargeInteger; LargeInteger.QuadPart = Int64Value;
FILETIME FileTime; FileTime.dwHighDateTime = LargeInteger.HighPart; FileTime.dwLowDateTime = LargeInteger.LowPart;
return FileTime; }
//------------------------------------------------------------------------
//
// NT security
//
//------------------------------------------------------------------------
SidHandle GetThreadClientSid();
HRESULT ImpersonateSid( PSID sid );
BOOL SidToString( PSID sid, wchar_t buffer[], USHORT bytes );
HRESULT IsRemoteUser();
HRESULT IsAdministratorUser();
HRESULT DenyRemoteAccess();
HRESULT DenyNonAdminAccess();
PSID DuplicateSid( PSID _Sid );
//
// allows CreateInstanceInSession to choose an arbitrary session.
//
#define ANY_SESSION DWORD(-1)
HRESULT CreateInstanceInSession( REFCLSID clsid, REFIID iid, DWORD session, void ** pif );
HRESULT SetStaticCloaking( IUnknown *pUnk );
HRESULT ApplyIdentityToInterface( IUnknown *pUnk, PSID sid );
struct IBackgroundCopyCallback; struct IBackgroundCopyCallback1;
HRESULT CreateUserCallback( CLSID clsid, PSID sid, IBackgroundCopyCallback **pICB );
HRESULT CreateOldUserCallback( CLSID clsid, PSID sid, IBackgroundCopyCallback1 **pICB );
HRESULT SessionLogonCallback( DWORD SessionId );
HRESULT SessionLogoffCallback( DWORD SessionId );
DWORD DeviceEventCallback( DWORD dwEventType, LPVOID lpEventData );
BOOL Log_Init(); void Log_StartLogger(); void Log_Close();
HRESULT GlobalInit(); HRESULT GlobalUninit();
HRESULT InitQmgr(); HRESULT UninitQmgr();
const GUID BITSCtrlGuid = {0x4a8aaa94,0xcfc4,0x46a7,{0x8e,0x4e,0x17,0xbc,0x45,0x60,0x8f,0x0a}};
#define WPP_CONTROL_GUIDS \
WPP_DEFINE_CONTROL_GUID(CtlGuid,(4a8aaa94,cfc4,46a7,8e4e,17bc45608f0a), \ WPP_DEFINE_BIT(LogFlagInfo) \ WPP_DEFINE_BIT(LogFlagWarning) \ WPP_DEFINE_BIT(LogFlagError) \ WPP_DEFINE_BIT(LogFlagFunction) \ WPP_DEFINE_BIT(LogFlagRefCount) \ WPP_DEFINE_BIT(LogFlagSerialize) \ WPP_DEFINE_BIT(LogFlagDownload) \ WPP_DEFINE_BIT(LogFlagTask) \ WPP_DEFINE_BIT(LogFlagLock) \ WPP_DEFINE_BIT(LogFlagService) \ )
#define LogLevelEnabled(flags) WPP_LEVEL_ENABLED(flags) \
LONG ExternalFuncExceptionFilter( struct _EXCEPTION_POINTERS *ExceptionInfo );
//
// We keep track of COM calls because we can't delete our objects at shutdown
// until all the active calls have stopped referring to them.
//
extern long g_cCalls;
inline void IncrementCallCount() { InterlockedIncrement(&g_cCalls); }
inline void DecrementCallCount() { InterlockedDecrement(&g_cCalls); }
inline long ActiveCallCount() { return g_cCalls; }
//
// A simple helper class to keep track of our call count.
//
class DispatchedCall { public: DispatchedCall() { IncrementCallCount(); } ~DispatchedCall() { DecrementCallCount(); } };
//
// Each member function of our public COM interfaces has an external
// and an internal version. The external version is simply
// {
// EXTERNAL_FUNC_WRAP( internal-version );
// }
// This captures any exceptions in a way that can be reported by the OfficeWatson
// error-reporting apparatus.
// It also checks for service shutdown.
//
HRESULT CheckServerInstance( long ObjectServiceInstance );
#define EXTERNAL_FUNC_WRAP( call_parent ) \
\ __try \ { \ RETURN_HRESULT( CheckServerInstance( m_ServiceInstance )); \ \ HRESULT hr = call_parent ; \ \ DecrementCallCount(); \ return hr; \ } \ __except( ExternalFuncExceptionFilter( GetExceptionInformation() ) ) \ { \ DecrementCallCount(); \ return RPC_E_SERVERFAULT; \ } \
//
// IUnknown member functions use these alternate macros.
//
#define BEGIN_EXTERNAL_FUNC \
__try \ { \
#define END_EXTERNAL_FUNC \
} \ __except( ExternalFuncExceptionFilter( GetExceptionInformation() ) ) \ { \ return RPC_E_SERVERFAULT; \ } \
StringHandle BITSCrackFileName( const WCHAR * RawFileName, StringHandle & ReturnFileName );
StringHandle BITSCreateTempFile( StringHandle Directory );
HRESULT BITSCheckFileWritability( LPCWSTR name );
StringHandle CombineUrl( LPCWSTR BaseUrl, LPCWSTR RelativeUrl, DWORD Flags );
LPWSTR MidlCopyString( LPCWSTR source, size_t Length = -1);
inline LPWSTR MidlCopyString( StringHandle source ) { return MidlCopyString( source, source.Size()+1 ); }
LPWSTR CopyString( LPCWSTR source, size_t Length = -1);
inline LPWSTR CopyString( StringHandle source ) { return CopyString( source, source.Size()+1 ); }
inline bool operator==( const FILETIME left, const FILETIME right ) { return ((left.dwLowDateTime == right.dwLowDateTime) && (left.dwHighDateTime == right.dwHighDateTime)); }
inline bool operator!=( const FILETIME left, const FILETIME right ) { return !(left == right); }
bool IsServiceShuttingDown();
bool IsAnyDebuggerPresent();
bool InitCompilerLibrary(); bool UninitCompilerLibrary();
#if defined(BITS_V12_ON_NT4)
extern ULONG BITSFlags; void Log( const CHAR *Prefix, const CHAR *Format, va_list ArgList );
const DWORD LogFlagInfo = 0; const DWORD LogFlagWarning = 1; const DWORD LogFlagError = 2; const DWORD LogFlagFunction = 4; const DWORD LogFlagRefCount = 8; const DWORD LogFlagRef = LogFlagRefCount; const DWORD LogFlagSerialize = 16; const DWORD LogFlagSerial = LogFlagSerialize; const DWORD LogFlagDownload = 32; const DWORD LogFlagDl = LogFlagDownload; const DWORD LogFlagTask = 64; const DWORD LogFlagLock = 128; const DWORD LogFlagService = 256; const DWORD LogFlagPublicApiBegin = LogFlagFunction; const DWORD LogFlagPublicApiEnd = LogFlagFunction;
#define DEFINE_SIMPLE_LOG_FUNCT( flag, prefix ) \
inline void Log##flag##( const char *format, ...) \ { \ if ( ! ( BITSFlags & ~LogFlag##flag ) ) \ return; \ va_list marker; \ va_start( marker, format ); \ Log( prefix, format, marker ); \ } \
DEFINE_SIMPLE_LOG_FUNCT( Info, " INFO :" ) DEFINE_SIMPLE_LOG_FUNCT( Warning, " WARNING :" ) DEFINE_SIMPLE_LOG_FUNCT( Error, " ERROR :" ) DEFINE_SIMPLE_LOG_FUNCT( PublicApiBegin, " FUNC_BEGIN :" ) DEFINE_SIMPLE_LOG_FUNCT( PublicApiEnd, " FUNC_END :" ) DEFINE_SIMPLE_LOG_FUNCT( Ref, " REF :" ) DEFINE_SIMPLE_LOG_FUNCT( Lock, " LOCK :" ) DEFINE_SIMPLE_LOG_FUNCT( Task, " TASK :" ) DEFINE_SIMPLE_LOG_FUNCT( Service, " SERVICE :" ) DEFINE_SIMPLE_LOG_FUNCT( Dl, " DOWNLOAD :" ) DEFINE_SIMPLE_LOG_FUNCT( Serial, " SERIALIZE :" )
BOOL BITSAltGetFileSizeEx( HANDLE hFile, // handle to file
PLARGE_INTEGER lpFileSize // file size
);
BOOL BITSAltSetFilePointerEx( HANDLE hFile, // handle to file
LARGE_INTEGER liDistanceToMove, // bytes to move pointer
PLARGE_INTEGER lpNewFilePointer, // new file pointer
DWORD dwMoveMethod // starting point
);
BOOL BITSAltConvertSidToStringSidW( IN PSID Sid, OUT LPWSTR *StringSid );
BOOL BITSAltConvertStringSidToSidW( IN LPCWSTR StringSid, OUT PSID *Sid );
BOOL BITSAltCheckTokenMembership( IN HANDLE TokenHandle OPTIONAL, IN PSID SidToCheck, OUT PBOOL IsMember );
SERVICE_STATUS_HANDLE BITSAltRegisterServiceCtrlHandlerExW( LPCTSTR lpServiceName, // name of service
LPHANDLER_FUNCTION_EX lpHandlerProc, // handler function
LPVOID lpContext // user data
);
#define GetFileSizeEx BITSAltGetFileSizeEx
#define SetFilePointerEx BITSAltSetFilePointerEx
#define ConvertSidToStringSidW BITSAltConvertSidToStringSidW
#define ConvertStringSidToSidW BITSAltConvertStringSidToSidW
#define CheckTokenMembership BITSAltCheckTokenMembership
#define RegisterServiceCtrlHandlerExW BITSAltRegisterServiceCtrlHandlerExW
#endif
|