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.
 
 
 
 
 
 

450 lines
11 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
precomp.h
Abstract:
Main header for BITS server extensions
--*/
#define INITGUID
#include<nt.h>
#include<ntrtl.h>
#include<nturtl.h>
#include <windows.h>
#include <httpfilt.h>
#include <httpext.h>
#include <objbase.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <iadmw.h>
#include <iiscnfg.h>
#include <shlwapi.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <sddl.h>
#include <aclapi.h>
#include "winhttp.h"
// #include "inethttp.h"
#include <activeds.h>
#include <bitsmsg.h>
#include "resource.h"
#include <smartptr.h>
typedef StringHandleA StringHandle;
#include <bitscfg.h>
typedef SmartRefPointer<IMSAdminBase> SmartMetabasePointer;
typedef SmartRefPointer<IBITSExtensionSetupFactory> SmartBITSExtensionSetupFactoryPointer;
typedef SmartRefPointer<IBITSExtensionSetup> SmartBITSExtensionSetupPointer;
#if defined(DBG)
// check build
#define BITS_MUST_SUCCEED( expr ) ASSERT( expr )
#else
// free build
#define BITS_MUST_SUCCEED( expr ) ( expr )
#endif
const UINT32 LOG_INFO = 0x1;
const UINT32 LOG_WARNING = 0x2;
const UINT32 LOG_ERROR = 0x4;
const UINT32 LOG_CALLBEGIN = 0x8;
const UINT32 LOG_CALLEND = 0x10;
#if defined(DBG)
const UINT32 DEFAULT_LOG_FLAGS = LOG_INFO | LOG_WARNING | LOG_ERROR | LOG_CALLBEGIN | LOG_CALLEND;
#else
const UINT32 DEFAULT_LOG_FLAGS = 0;
#endif
const UINT32 DEFAULT_LOG_SIZE = 20;
// LogSetings path under HKEY_LOCAL_MACHINE
const char * const LOG_SETTINGS_PATH = "SOFTWARE\\Microsoft\\BITSServer";
// Values
// (REG_EXPAND_SZ). Contains the full path of the log file name
const char * const LOG_FILENAME_VALUE = "LogFileName";
// (REG_DWORD) Contains the log flags
const char * const LOG_FLAGS_VALUE = "LogFlags";
// (REG_DWORD) Contains the log size in MB
const char * const LOG_SIZE_VALUE = "LogSize";
// (REG_DWORD) Indicates if we will be appending the ProcessId to the log file name
const char * const PER_PROCESS_LOG_VALUE = "PerProcessLog";
extern UINT32 g_LogFlags;
HRESULT LogInit();
void LogClose();
void LogInternal( UINT32 LogFlags, char *Format, va_list arglist );
void inline Log( UINT32 LogFlags, char *Format, ... )
{
if ( !( g_LogFlags & LogFlags ) )
return;
va_list arglist;
va_start( arglist, Format );
LogInternal( LogFlags, Format, arglist );
}
const char *LookupHTTPStatusCodeText( DWORD HttpCode );
class ServerException : public ComError
{
public:
ServerException() :
ComError( 0 ),
m_HttpCode( 0 ),
m_Context( 0 )
{
}
ServerException( HRESULT Code, DWORD HttpCode = 0, DWORD Context = 0x5 ) :
ComError( Code ),
m_HttpCode( HttpCode ? HttpCode : MapStatus( Code ) ),
m_Context( Context )
{
}
ServerException( const ComError & Error ) :
ComError( Error.m_Hr ),
m_HttpCode( MapStatus( Error.m_Hr ) ),
m_Context( 0x5 )
{
}
ServerException( const ServerException & Error ) :
ComError( Error.m_Hr ),
m_HttpCode( Error.m_HttpCode ),
m_Context( Error.m_Context )
{
}
HRESULT GetCode() const
{
return m_Hr;
}
DWORD GetHttpCode() const
{
return m_HttpCode;
}
DWORD GetContext() const
{
return m_Context;
}
void SendErrorResponse( EXTENSION_CONTROL_BLOCK * ExtensionControlBlock ) const;
DWORD MapStatus( HRESULT Hr ) const;
private:
DWORD m_HttpCode;
DWORD m_Context;
};
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;
}
// API thunks
UINT64 BITSGetFileSize(
HANDLE Handle );
UINT64 BITSSetFilePointer(
HANDLE Handle,
INT64 Distance,
DWORD MoveMethod );
DWORD
BITSWriteFile(
HANDLE Handle,
LPCVOID Buffer,
DWORD NumberOfBytesToWrite);
void
BITSCreateDirectory(
const CHAR *Path );
void
BITSRenameFile(
LPCTSTR ExistingName,
LPCTSTR NewName,
bool AllowOverwrites );
void
BITSDeleteFile(
LPCTSTR FileName );
GUID
BITSCreateGuid();
GUID
BITSGuidFromString( const char *String );
StringHandle
BITSStringFromGuid(
GUID Guid );
StringHandle
BITSUnicodeToStringHandle( const WCHAR *pStr );
StringHandle
BITSUrlCombine(
const char *Base,
const char *Relative,
DWORD dwFlags );
StringHandle
BITSUrlCanonicalize(
const char *URL,
DWORD dwFlags );
void
BITSSetCurrentThreadToken(
HANDLE hToken );
// Metadata wrappers
StringHandle
GetMetaDataString(
IMSAdminBase *IISAdminBase,
METADATA_HANDLE Handle,
LPCWSTR Path,
DWORD dwIdentifier,
LPCSTR DefaultValue );
DWORD
GetMetaDataDWORD(
IMSAdminBase *IISAdminBase,
METADATA_HANDLE Handle,
LPCWSTR Path,
DWORD dwIdentifier,
DWORD DefaultValue );
class WorkStringBufferA
{
char *Data;
public:
WorkStringBufferA( SIZE_T Size )
{
Data = new char[Size];
}
WorkStringBufferA( const char* String )
{
size_t BufferSize = strlen(String) + 1;
Data = new char[ BufferSize ];
memcpy( Data, String, BufferSize );
}
~WorkStringBufferA()
{
delete[] Data;
}
char *GetBuffer()
{
return Data;
}
};
class WorkStringBufferW
{
WCHAR *Data;
public:
WorkStringBufferW( SIZE_T Size )
{
Data = new WCHAR[Size];
}
WorkStringBufferW( const WCHAR* String )
{
size_t BufferSize = wcslen(String) + 1;
Data = new WCHAR[ BufferSize ];
memcpy( Data, String, BufferSize * sizeof( WCHAR ) );
}
~WorkStringBufferW()
{
delete[] Data;
}
WCHAR *GetBuffer()
{
return Data;
}
};
typedef WorkStringBufferA WorkStringBuffer;
const char * const BITS_CONNECTIONS_NAME_WITH_SLASH="BITS-Connections\\";
const char * const BITS_CONNECTIONS_NAME="BITS-Connections";
const UINT64 NanoSec100PerSec = 10000000; //no of 100 nanosecs per sec
const DWORD WorkerRunInterval = 1000 * 60 /*secs*/ * 60 /*mins*/ * 12; /* hours */ /* twice a day */
const UINT64 CleanupThreshold = NanoSec100PerSec * 60 /*secs*/ * 60 /*mins*/ * 24 /* hours */ * 3; // 3 days
//
// Configuration manager
//
#include "bitssrvcfg.h"
class ConfigurationManager;
class VDirConfig
{
friend ConfigurationManager;
LONG m_Refs;
FILETIME m_LastLookup;
static StringHandle GetFullPath( StringHandle Path );
public:
StringHandle m_Path;
StringHandle m_PhysicalPath;
StringHandle m_SessionDir;
StringHandle m_ConnectionsDir;
StringHandle m_RequestsDir;
StringHandle m_RepliesDir;
DWORD m_NoProgressTimeout;
UINT64 m_MaxFileSize;
BITS_SERVER_NOTIFICATION_TYPE m_NotificationType;
StringHandle m_NotificationURL;
bool m_UploadEnabled;
StringHandle m_HostId;
DWORD m_HostIdFallbackTimeout;
DWORD m_ExecutePermissions;
bool m_AllowOverwrites;
VDirConfig(
StringHandle Path,
SmartMetabasePointer AdminBase );
void AddRef()
{
InterlockedIncrement( &m_Refs );
}
void Release()
{
if (!InterlockedDecrement( &m_Refs ))
delete this;
}
};
typedef SmartRefPointer<VDirConfig> SmartVDirConfig;
class MapCacheEntry
{
friend ConfigurationManager;
FILETIME m_LastLookup;
public:
StringHandle m_InstanceMetabasePath;
StringHandle m_URL;
SmartVDirConfig m_Config;
DWORD m_URLDepth;
MapCacheEntry(
StringHandle InstanceMetabasePath,
StringHandle URL,
SmartVDirConfig Config,
DWORD URLDepth ) :
m_InstanceMetabasePath( InstanceMetabasePath ),
m_URL( URL ),
m_Config( Config ),
m_URLDepth( URLDepth )
{
GetSystemTimeAsFileTime( &m_LastLookup );
}
};
class ConfigurationManager
{
public:
ConfigurationManager();
~ConfigurationManager();
SmartVDirConfig GetConfig2( StringHandle InstanceMetabasePath, StringHandle URL,
DWORD *pURLDepth );
SmartVDirConfig GetConfig( StringHandle InstanceMetabasePath, StringHandle URL,
DWORD *pURLDepth );
static const PATH_CACHE_ENTRIES = 10;
static const MAP_CACHE_ENTRIES = 10;
private:
SmartMetabasePointer m_IISAdminBase;
CRITICAL_SECTION m_CacheCS;
DWORD m_ChangeNumber;
SmartVDirConfig m_PathCacheEntries[ PATH_CACHE_ENTRIES ];
MapCacheEntry *m_MapCacheEntries[ MAP_CACHE_ENTRIES ];
void FlushCache();
bool HandleCacheConsistency();
// L2 cache
SmartVDirConfig Lookup( StringHandle Path );
void Insert( SmartVDirConfig NewConfig );
SmartVDirConfig GetVDirConfig( StringHandle Path );
// L1 cache
SmartVDirConfig Lookup( StringHandle InstanceMetabasePath,
StringHandle URL,
DWORD *pURLDepth );
SmartVDirConfig Insert( StringHandle InstanceMetabasePath,
StringHandle URL,
StringHandle Path,
DWORD URLDepth );
StringHandle GetVDirPath( StringHandle InstanceMetabasePath,
StringHandle URL,
DWORD *pURLDepth );
};
extern ConfigurationManager *g_ConfigMan;
extern HMODULE g_hinst;
extern PropertyIDManager *g_PropertyMan;