2660 lines
67 KiB
C++
2660 lines
67 KiB
C++
|
/************************************************************************
|
||
|
|
||
|
Copyright (c) 2001 Microsoft Corporation
|
||
|
|
||
|
Module Name :
|
||
|
|
||
|
bitsext.cpp
|
||
|
|
||
|
Abstract :
|
||
|
|
||
|
Main snapin code.
|
||
|
|
||
|
Author :
|
||
|
|
||
|
Revision History :
|
||
|
|
||
|
***********************************************************************/
|
||
|
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
bool CPropSheetExtension::s_bStaticInitialized = false;
|
||
|
UINT CPropSheetExtension::s_cfDisplayName;
|
||
|
UINT CPropSheetExtension::s_cfSnapInCLSID;
|
||
|
UINT CPropSheetExtension::s_cfNodeType;
|
||
|
UINT CPropSheetExtension::s_cfSnapInMetapath;
|
||
|
UINT CPropSheetExtension::s_cfSnapInMachineName;
|
||
|
|
||
|
const UINT CPropSheetExtension::s_MaxUploadUnits[] =
|
||
|
{
|
||
|
IDS_BYTES,
|
||
|
IDS_KILOBYTES,
|
||
|
IDS_MEGABYTES,
|
||
|
IDS_GIGABYTES,
|
||
|
IDS_TERABYTES
|
||
|
|
||
|
};
|
||
|
const UINT CPropSheetExtension::s_NumberOfMaxUploadUnits =
|
||
|
sizeof(CPropSheetExtension::s_MaxUploadUnits)/
|
||
|
sizeof(*CPropSheetExtension::s_MaxUploadUnits);
|
||
|
|
||
|
const UINT64 CPropSheetExtension::s_MaxUploadUnitsScales[] =
|
||
|
{
|
||
|
1,
|
||
|
1024,
|
||
|
1048576,
|
||
|
1073741824,
|
||
|
1099511627776
|
||
|
};
|
||
|
const UINT CPropSheetExtension::s_NumberOfMaxUploadUnitsScales =
|
||
|
sizeof(CPropSheetExtension::s_MaxUploadUnitsScales)/
|
||
|
sizeof(*CPropSheetExtension::s_MaxUploadUnitsScales);
|
||
|
|
||
|
|
||
|
const UINT64 CPropSheetExtension::s_MaxUploadLimits[] =
|
||
|
{
|
||
|
18446744073709551615, //bytes
|
||
|
18014398509481983, //kilobytes
|
||
|
17592186044415, //megabytes
|
||
|
17179869183, //gigabytes
|
||
|
16777215 //terabytes
|
||
|
|
||
|
};
|
||
|
|
||
|
const UINT CPropSheetExtension::s_NumberOfMaxUploadLimits=
|
||
|
sizeof(CPropSheetExtension::s_MaxUploadLimits)/
|
||
|
sizeof(*CPropSheetExtension::s_MaxUploadLimits);
|
||
|
|
||
|
const UINT CPropSheetExtension::s_TimeoutUnits[] =
|
||
|
{
|
||
|
IDS_SECONDS,
|
||
|
IDS_MINUTES,
|
||
|
IDS_HOURS,
|
||
|
IDS_DAYS
|
||
|
};
|
||
|
const UINT CPropSheetExtension::s_NumberOfTimeoutUnits =
|
||
|
sizeof(CPropSheetExtension::s_TimeoutUnits)/
|
||
|
sizeof(*CPropSheetExtension::s_TimeoutUnits);
|
||
|
|
||
|
|
||
|
const DWORD CPropSheetExtension::s_TimeoutUnitsScales[] =
|
||
|
{
|
||
|
1,
|
||
|
60,
|
||
|
60*60,
|
||
|
24*60*60
|
||
|
};
|
||
|
const UINT CPropSheetExtension::s_NumberOfTimeoutUnitsScales =
|
||
|
sizeof(CPropSheetExtension::s_TimeoutUnitsScales)/
|
||
|
sizeof(*CPropSheetExtension::s_TimeoutUnitsScales);
|
||
|
|
||
|
const UINT64 CPropSheetExtension::s_TimeoutLimits[] =
|
||
|
{
|
||
|
4294967295, // seconds
|
||
|
71582788, // minutes
|
||
|
1193046, // hours
|
||
|
49710 // days
|
||
|
};
|
||
|
|
||
|
const UINT CPropSheetExtension::s_NumberOfTimeoutLimits =
|
||
|
sizeof(CPropSheetExtension::s_TimeoutLimits)/
|
||
|
sizeof(*CPropSheetExtension::s_TimeoutLimits);
|
||
|
|
||
|
|
||
|
const UINT CPropSheetExtension::s_NotificationTypes[] =
|
||
|
{
|
||
|
IDS_BYREF_POST_NOTIFICATION,
|
||
|
IDS_BYVAL_POST_NOTIFICATION
|
||
|
|
||
|
};
|
||
|
|
||
|
const UINT CPropSheetExtension::s_NumberOfNotificationTypes =
|
||
|
sizeof(CPropSheetExtension::s_NotificationTypes)/
|
||
|
sizeof(*CPropSheetExtension::s_NotificationTypes);
|
||
|
|
||
|
HRESULT CPropSheetExtension::InitializeStatic()
|
||
|
{
|
||
|
|
||
|
if ( s_bStaticInitialized )
|
||
|
return S_OK;
|
||
|
|
||
|
if ( !( s_cfDisplayName = RegisterClipboardFormat(L"CCF_DISPLAY_NAME") ) ||
|
||
|
!( s_cfNodeType = RegisterClipboardFormat(L"CCF_NODETYPE") ) ||
|
||
|
!( s_cfSnapInCLSID = RegisterClipboardFormat(L"CCF_SNAPIN_CLASSID") ) ||
|
||
|
!( s_cfSnapInMetapath = RegisterClipboardFormat(L"ISM_SNAPIN_META_PATH") ) ||
|
||
|
!( s_cfSnapInMachineName = RegisterClipboardFormat(L"ISM_SNAPIN_MACHINE_NAME") ) )
|
||
|
return HRESULT_FROM_WIN32( GetLastError() );
|
||
|
|
||
|
s_bStaticInitialized = true;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
CPropSheetExtension::InheritedValues::InheritedValues() :
|
||
|
MaxUploadSize(0),
|
||
|
SessionTimeout(0),
|
||
|
NotificationType( BITS_NOTIFICATION_TYPE_NONE ),
|
||
|
NotificationURL( NULL ),
|
||
|
HostId( NULL ),
|
||
|
FallbackTimeout( 0 )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CPropSheetExtension::InheritedValues::~InheritedValues()
|
||
|
{
|
||
|
delete NotificationURL;
|
||
|
delete HostId;
|
||
|
}
|
||
|
|
||
|
CPropSheetExtension::CPropSheetExtension() :
|
||
|
m_cref(1),
|
||
|
m_MetabasePath( NULL ),
|
||
|
m_MetabaseParent( NULL ),
|
||
|
m_ComputerName( NULL ),
|
||
|
m_UNCComputerName( NULL ),
|
||
|
m_IISAdminBase( NULL ),
|
||
|
m_IBITSSetup( NULL ),
|
||
|
m_PropertyMan( NULL ),
|
||
|
m_hwnd( NULL ),
|
||
|
m_SettingsChanged( false ),
|
||
|
m_EnabledSettingChanged( false ),
|
||
|
m_TaskSched( NULL ),
|
||
|
m_CleanupTask( NULL ),
|
||
|
m_CleanupInProgress( false ),
|
||
|
m_CleanupCursor( NULL ),
|
||
|
m_CleanupMinWaitTimerFired( false )
|
||
|
{
|
||
|
OBJECT_CREATED
|
||
|
}
|
||
|
|
||
|
CPropSheetExtension::~CPropSheetExtension()
|
||
|
{
|
||
|
CloseCleanupItems(); // Close m_TaskSched and m_CleanupTask
|
||
|
|
||
|
delete m_MetabasePath;
|
||
|
delete m_MetabaseParent;
|
||
|
delete m_ComputerName;
|
||
|
delete m_UNCComputerName;
|
||
|
|
||
|
if ( m_IBITSSetup )
|
||
|
m_IBITSSetup->Release();
|
||
|
|
||
|
if ( m_IISAdminBase )
|
||
|
m_IISAdminBase->Release();
|
||
|
|
||
|
delete m_PropertyMan;
|
||
|
|
||
|
OBJECT_DESTROYED
|
||
|
}
|
||
|
|
||
|
///////////////////////
|
||
|
// IUnknown implementation
|
||
|
///////////////////////
|
||
|
|
||
|
STDMETHODIMP CPropSheetExtension::QueryInterface(REFIID riid, LPVOID *ppv)
|
||
|
{
|
||
|
if (!ppv)
|
||
|
return E_FAIL;
|
||
|
|
||
|
*ppv = NULL;
|
||
|
|
||
|
if (IsEqualIID(riid, IID_IUnknown))
|
||
|
*ppv = static_cast<IExtendPropertySheet *>(this);
|
||
|
else if (IsEqualIID(riid, IID_IExtendPropertySheet))
|
||
|
*ppv = static_cast<IExtendPropertySheet *>(this);
|
||
|
|
||
|
if (*ppv)
|
||
|
{
|
||
|
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CPropSheetExtension::AddRef()
|
||
|
{
|
||
|
return InterlockedIncrement((LONG *)&m_cref);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CPropSheetExtension::Release()
|
||
|
{
|
||
|
if (InterlockedDecrement((LONG *)&m_cref) == 0)
|
||
|
{
|
||
|
// we need to decrement our object count in the DLL
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return m_cref;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::ExtractData(
|
||
|
IDataObject* piDataObject,
|
||
|
CLIPFORMAT cfClipFormat,
|
||
|
BYTE* pbData,
|
||
|
DWORD cbData )
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
FORMATETC formatetc = {cfClipFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||
|
STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL};
|
||
|
|
||
|
stgmedium.hGlobal = ::GlobalAlloc(GPTR, cbData);
|
||
|
do // false loop
|
||
|
{
|
||
|
if (NULL == stgmedium.hGlobal)
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
break;
|
||
|
}
|
||
|
hr = piDataObject->GetDataHere( &formatetc, &stgmedium );
|
||
|
if ( FAILED(hr) )
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
BYTE* pbNewData = reinterpret_cast<BYTE*>(stgmedium.hGlobal);
|
||
|
if (NULL == pbNewData)
|
||
|
{
|
||
|
hr = E_UNEXPECTED;
|
||
|
break;
|
||
|
}
|
||
|
::memcpy( pbData, pbNewData, cbData );
|
||
|
} while (FALSE); // false loop
|
||
|
|
||
|
if (NULL != stgmedium.hGlobal)
|
||
|
{
|
||
|
::GlobalFree(stgmedium.hGlobal);
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::ExtractSnapInString( IDataObject * piDataObject,
|
||
|
WCHAR * & String,
|
||
|
UINT Format )
|
||
|
{
|
||
|
|
||
|
HRESULT Hr = S_OK;
|
||
|
|
||
|
if ( String )
|
||
|
return S_OK;
|
||
|
|
||
|
FORMATETC formatetc = {(CLIPFORMAT)Format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||
|
STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL };
|
||
|
|
||
|
stgmedium.hGlobal = GlobalAlloc( GMEM_MOVEABLE, 0 );
|
||
|
if ( !stgmedium.hGlobal )
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
Hr = piDataObject->GetDataHere(&formatetc, &stgmedium);
|
||
|
|
||
|
if (FAILED(Hr))
|
||
|
{
|
||
|
ReleaseStgMedium(&stgmedium);
|
||
|
return Hr;
|
||
|
}
|
||
|
|
||
|
WCHAR* pRetData = (WCHAR*)GlobalLock( stgmedium.hGlobal );
|
||
|
|
||
|
SIZE_T StringLength = wcslen( pRetData ) + 1;
|
||
|
|
||
|
String = new WCHAR[ StringLength ];
|
||
|
|
||
|
if ( !String )
|
||
|
{
|
||
|
GlobalUnlock( pRetData );
|
||
|
ReleaseStgMedium( &stgmedium );
|
||
|
return E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
StringCchCopyW( String, StringLength, pRetData );
|
||
|
|
||
|
GlobalUnlock( pRetData );
|
||
|
ReleaseStgMedium( &stgmedium );
|
||
|
|
||
|
return S_OK;
|
||
|
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::ExtractSnapInGUID(
|
||
|
IDataObject * piDataObject,
|
||
|
GUID & Guid,
|
||
|
UINT Format )
|
||
|
{
|
||
|
|
||
|
HRESULT Hr = S_OK;
|
||
|
|
||
|
FORMATETC formatetc = {(CLIPFORMAT)Format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||
|
STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL };
|
||
|
|
||
|
stgmedium.hGlobal = GlobalAlloc( GMEM_MOVEABLE, 0 );
|
||
|
if ( !stgmedium.hGlobal )
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
Hr = piDataObject->GetDataHere(&formatetc, &stgmedium);
|
||
|
|
||
|
if (FAILED(Hr))
|
||
|
{
|
||
|
ReleaseStgMedium(&stgmedium);
|
||
|
return Hr;
|
||
|
}
|
||
|
|
||
|
GUID * pRetData = (GUID*)GlobalLock( stgmedium.hGlobal );
|
||
|
|
||
|
Guid = *pRetData;
|
||
|
GlobalUnlock( pRetData );
|
||
|
ReleaseStgMedium( &stgmedium );
|
||
|
|
||
|
return S_OK;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::AddComboBoxItems(
|
||
|
UINT Combo,
|
||
|
const UINT *Items,
|
||
|
UINT NumberOfItems )
|
||
|
{
|
||
|
HWND hwndBox = GetDlgItem( m_hwnd, Combo );
|
||
|
|
||
|
SendMessage( hwndBox, CB_RESETCONTENT, 0, 0 );
|
||
|
for( unsigned int i = 0; i < NumberOfItems; i++ )
|
||
|
{
|
||
|
|
||
|
WCHAR ItemText[MAX_PATH];
|
||
|
|
||
|
LoadString( g_hinst, Items[i], ItemText, MAX_PATH-1 );
|
||
|
SendMessage( hwndBox, CB_ADDSTRING, 0, (LPARAM)ItemText );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::UpdateMaxUploadGroupState(
|
||
|
bool IsEnabled )
|
||
|
{
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_CHECK_LIMIT_MAX_UPLOAD ), IsEnabled );
|
||
|
|
||
|
bool SubgroupEnabled = IsEnabled && ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_LIMIT_MAX_UPLOAD ) );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_EDIT_MAX_UPLOAD ), SubgroupEnabled );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_COMBO_MAX_UPLOAD_UNITS ), SubgroupEnabled );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::UpdateTimeoutGroupState(
|
||
|
bool IsEnabled )
|
||
|
{
|
||
|
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_DELETE_FILES ), IsEnabled );
|
||
|
|
||
|
bool SubgroupEnabled = IsEnabled && ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_DELETE_FILES ) );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_EDIT_SESSION_TIMEOUT ), SubgroupEnabled );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_COMBO_SESSION_TIMEOUT_UNITS ), SubgroupEnabled );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::UpdateNotificationsGroupState(
|
||
|
bool IsEnabled )
|
||
|
{
|
||
|
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_CHECK_ENABLE_NOTIFICATIONS ), IsEnabled );
|
||
|
|
||
|
bool SubgroupEnabled = IsEnabled && ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_ENABLE_NOTIFICATIONS ) );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_STATIC_NOTIFICATION_TYPE ), SubgroupEnabled );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_COMBO_NOTIFICATION_TYPE ), SubgroupEnabled );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_STATIC_NOTIFICATION_URL ), SubgroupEnabled );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_EDIT_NOTIFICATION_URL ), SubgroupEnabled );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::UpdateServerFarmFallbackGroupState(
|
||
|
bool IsEnabled )
|
||
|
{
|
||
|
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_CHECK_FALLBACK_TIMEOUT ), IsEnabled );
|
||
|
|
||
|
bool SubgroupEnabled = IsEnabled && ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_FALLBACK_TIMEOUT ) );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_EDIT_FALLBACK_TIMEOUT ), SubgroupEnabled );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_COMBO_FALLBACK_TIMEOUT_UNITS ), SubgroupEnabled );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::UpdateServerFarmGroupState(
|
||
|
bool IsEnabled )
|
||
|
{
|
||
|
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_ENABLE_SERVER_FARM ), IsEnabled );
|
||
|
|
||
|
bool SubgroupEnabled = IsEnabled && ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_ENABLE_SERVER_FARM ) );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_STATIC_RECONNECT ), SubgroupEnabled );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_EDIT_HOSTID ), SubgroupEnabled );
|
||
|
UpdateServerFarmFallbackGroupState( SubgroupEnabled );
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::UpdateConfigGroupState(
|
||
|
bool IsEnabled )
|
||
|
{
|
||
|
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_RADIO_USE_INHERITED_CONFIG ), IsEnabled );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_RADIO_USE_CUSTOM_CONFIG ), IsEnabled );
|
||
|
|
||
|
bool UseCustomConfig = false;
|
||
|
|
||
|
if ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_RADIO_USE_CUSTOM_CONFIG ) )
|
||
|
UseCustomConfig = true;
|
||
|
|
||
|
bool SubgroupEnabled = IsEnabled && UseCustomConfig;
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_STATIC_CUSTOM_CONFIG ), SubgroupEnabled );
|
||
|
UpdateMaxUploadGroupState( SubgroupEnabled );
|
||
|
UpdateTimeoutGroupState( SubgroupEnabled );
|
||
|
UpdateServerFarmGroupState( SubgroupEnabled );
|
||
|
UpdateNotificationsGroupState( SubgroupEnabled );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::UpdateUploadGroupState()
|
||
|
{
|
||
|
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_CHECK_BITS_UPLOAD ), true );
|
||
|
|
||
|
bool IsUploadEnabled = ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_BITS_UPLOAD ) );
|
||
|
|
||
|
UpdateConfigGroupState( IsUploadEnabled );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::UpdateCleanupState()
|
||
|
{
|
||
|
|
||
|
bool IsEnabled = ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_BITS_UPLOAD ) );
|
||
|
HRESULT Hr;
|
||
|
|
||
|
if ( IsEnabled )
|
||
|
{
|
||
|
|
||
|
if ( !m_TaskSched )
|
||
|
{
|
||
|
|
||
|
Hr = ConnectToTaskScheduler( m_UNCComputerName, &m_TaskSched );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
DisplayError( IDS_CANT_CONNECT_TO_TASKSCHED, Hr );
|
||
|
IsEnabled = false;
|
||
|
goto setstate;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( !m_CleanupTask )
|
||
|
{
|
||
|
|
||
|
WCHAR KeyPath[ 255 ];
|
||
|
DWORD BufferDataLength;
|
||
|
|
||
|
METADATA_RECORD mdr;
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( MD_BITS_CLEANUP_WORKITEM_KEY );
|
||
|
mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = STRING_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)KeyPath;
|
||
|
mdr.dwMDDataLen = sizeof(KeyPath);
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferDataLength );
|
||
|
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
DisplayError( IDS_CANT_CONNECT_TO_TASKSCHED, Hr );
|
||
|
IsEnabled = false;
|
||
|
goto setstate;
|
||
|
}
|
||
|
|
||
|
Hr = FindWorkItemForVDIR(
|
||
|
m_TaskSched,
|
||
|
KeyPath,
|
||
|
&m_CleanupTask,
|
||
|
NULL );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
DisplayError( IDS_CANT_CONNECT_TO_TASKSCHED, Hr );
|
||
|
IsEnabled = false;
|
||
|
goto setstate;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
setstate:
|
||
|
|
||
|
if ( !IsEnabled )
|
||
|
CloseCleanupItems();
|
||
|
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_BUTTON_SCHEDULE_CLEANUP ), IsEnabled );
|
||
|
EnableWindow( GetDlgItem( m_hwnd, IDC_BUTTON_CLEANUP_NOW ), IsEnabled );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::CloseCleanupItems()
|
||
|
{
|
||
|
if ( m_TaskSched )
|
||
|
{
|
||
|
m_TaskSched->Release();
|
||
|
m_TaskSched = NULL;
|
||
|
}
|
||
|
|
||
|
if ( m_CleanupTask )
|
||
|
{
|
||
|
m_CleanupTask->Release();
|
||
|
m_CleanupTask = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::ScheduleCleanup()
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// Since the task scheduler caches most of the information,
|
||
|
// its necessary to close the task item and reopen it to refresh it.
|
||
|
// Do that now.
|
||
|
//
|
||
|
|
||
|
if ( m_CleanupTask )
|
||
|
{
|
||
|
m_CleanupTask->Release();
|
||
|
m_CleanupTask = NULL;
|
||
|
UpdateCleanupState();
|
||
|
}
|
||
|
|
||
|
if ( !m_CleanupTask )
|
||
|
return;
|
||
|
|
||
|
HRESULT Hr;
|
||
|
IProvideTaskPage *PropTaskPage = NULL;
|
||
|
|
||
|
const int NumberOfPages = 2;
|
||
|
TASKPAGE PageTypes[2] = { TASKPAGE_SCHEDULE, TASKPAGE_SETTINGS };
|
||
|
HPROPSHEETPAGE Pages[2] = { NULL, NULL };
|
||
|
|
||
|
Hr = m_CleanupTask->QueryInterface(
|
||
|
__uuidof(*PropTaskPage),
|
||
|
(void **)&PropTaskPage );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
goto error;
|
||
|
|
||
|
for( int i = 0; i < NumberOfPages; i++ )
|
||
|
{
|
||
|
|
||
|
Hr = PropTaskPage->GetPage( PageTypes[i], TRUE, Pages + i );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
goto error;
|
||
|
|
||
|
}
|
||
|
|
||
|
PropTaskPage->Release();
|
||
|
PropTaskPage = NULL;
|
||
|
|
||
|
//
|
||
|
// Build TITLE for property page.
|
||
|
//
|
||
|
|
||
|
WCHAR TitleFormat[ MAX_PATH ];
|
||
|
WCHAR Title[ METADATA_MAX_NAME_LEN + MAX_PATH ];
|
||
|
const WCHAR *VDirName;
|
||
|
|
||
|
// Find last component of the metabase path.
|
||
|
// It should be the virtual directory name.
|
||
|
|
||
|
for ( VDirName = m_MetabasePath + wcslen( m_MetabasePath );
|
||
|
VDirName != m_MetabasePath && L'/' != *VDirName && L'\\' != *VDirName;
|
||
|
VDirName-- );
|
||
|
|
||
|
if ( VDirName != m_MetabasePath )
|
||
|
VDirName++;
|
||
|
|
||
|
LoadString( g_hinst, IDS_WORK_ITEM_PROPERTY_PAGE_TITLE, TitleFormat, MAX_PATH-1 );
|
||
|
|
||
|
DWORD FormatResult =
|
||
|
FormatMessage(
|
||
|
FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||
|
(LPCVOID)TitleFormat,
|
||
|
0,
|
||
|
0,
|
||
|
(LPTSTR)Title,
|
||
|
( sizeof(Title) / sizeof(*Title) ) - 1,
|
||
|
(va_list*)&VDirName );
|
||
|
|
||
|
|
||
|
if ( !FormatResult )
|
||
|
{
|
||
|
Hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
|
||
|
PROPSHEETHEADER psh;
|
||
|
memset( &psh, 0, sizeof( psh ) );
|
||
|
psh.dwSize = sizeof(PROPSHEETHEADER);
|
||
|
psh.dwFlags = PSH_DEFAULT | PSH_NOAPPLYNOW;
|
||
|
psh.phpage = Pages;
|
||
|
psh.nPages = NumberOfPages;
|
||
|
psh.hwndParent = GetParent( m_hwnd );
|
||
|
psh.pszCaption = Title;
|
||
|
|
||
|
INT_PTR Result = PropertySheet(&psh);
|
||
|
|
||
|
if ( -1 == Result )
|
||
|
{
|
||
|
Hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
|
||
|
error:
|
||
|
|
||
|
for( int i = 0; i < NumberOfPages; i++ )
|
||
|
{
|
||
|
DestroyPropertySheetPage( Pages[i] );
|
||
|
}
|
||
|
|
||
|
if ( PropTaskPage )
|
||
|
PropTaskPage->Release();
|
||
|
|
||
|
DisplayError( IDS_CANT_START_CLEANUP_SCHEDULE, Hr );
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::CleanupNow()
|
||
|
{
|
||
|
|
||
|
HRESULT Hr;
|
||
|
HRESULT Status;
|
||
|
|
||
|
if ( m_CleanupInProgress )
|
||
|
return;
|
||
|
|
||
|
Hr = m_CleanupTask->GetStatus( &Status );
|
||
|
|
||
|
if ( FAILED(Hr) )
|
||
|
goto error;
|
||
|
|
||
|
SYSTEMTIME MostRecentRunTime;
|
||
|
Hr = m_CleanupTask->GetMostRecentRunTime( &MostRecentRunTime );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
goto error;
|
||
|
|
||
|
SYSTEMTIME EmptyTime;
|
||
|
memset( &EmptyTime, 0, sizeof(EmptyTime) );
|
||
|
|
||
|
if ( memcmp( &EmptyTime, &MostRecentRunTime, sizeof( EmptyTime ) ) == 0 )
|
||
|
{
|
||
|
// Job Has never been run
|
||
|
memset( &m_PrevCleanupStartTime, 0, sizeof(EmptyTime) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if ( !SystemTimeToFileTime( &MostRecentRunTime, &m_PrevCleanupStartTime ) )
|
||
|
{
|
||
|
Hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( SCHED_S_TASK_RUNNING != Status )
|
||
|
{
|
||
|
|
||
|
Hr = m_CleanupTask->Run();
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
goto error;
|
||
|
|
||
|
}
|
||
|
|
||
|
m_CleanupMinWaitTimerFired = false;
|
||
|
if ( !SetTimer( m_hwnd, s_CleanupMinWaitTimerID, s_CleanupMinWaitTimerInterval, NULL ) )
|
||
|
{
|
||
|
Hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
if ( !SetTimer( m_hwnd, s_CleanupPollTimerID, s_CleanupMinWaitTimerInterval, NULL ) )
|
||
|
{
|
||
|
Hr = HRESULT_FROM_WIN32( GetLastError() );
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
m_CleanupInProgress = true;
|
||
|
m_CleanupCursor = LoadCursor( NULL, (LPWSTR)IDC_WAIT );
|
||
|
SetCursor( m_CleanupCursor );
|
||
|
return;
|
||
|
|
||
|
error:
|
||
|
|
||
|
KillTimer( m_hwnd, s_CleanupMinWaitTimerID );
|
||
|
KillTimer( m_hwnd, s_CleanupPollTimerID );
|
||
|
SetCursor( (HCURSOR)GetClassLongPtr( m_hwnd, GCLP_HCURSOR ) );
|
||
|
DisplayError( IDS_CANT_START_CLEANUP, Hr );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::CleanupTimer(
|
||
|
UINT TimerID )
|
||
|
{
|
||
|
|
||
|
HRESULT Hr;
|
||
|
|
||
|
if ( s_CleanupMinWaitTimerID != TimerID &&
|
||
|
s_CleanupPollTimerID != TimerID )
|
||
|
return;
|
||
|
|
||
|
if ( s_CleanupMinWaitTimerID )
|
||
|
{
|
||
|
m_CleanupMinWaitTimerFired = true;
|
||
|
KillTimer( m_hwnd, s_CleanupMinWaitTimerID );
|
||
|
}
|
||
|
|
||
|
if ( !m_CleanupMinWaitTimerFired )
|
||
|
return; // keep cursor active for minimum time period
|
||
|
|
||
|
//
|
||
|
// Since the task scheduler caches most of the information,
|
||
|
// its necessary to close the task item and reopen it to refresh it.
|
||
|
// Do that now.
|
||
|
//
|
||
|
|
||
|
if ( m_CleanupTask )
|
||
|
{
|
||
|
m_CleanupTask->Release();
|
||
|
m_CleanupTask = NULL;
|
||
|
UpdateCleanupState();
|
||
|
}
|
||
|
|
||
|
if ( !m_CleanupTask )
|
||
|
{
|
||
|
// shut down the polling
|
||
|
KillTimer( m_hwnd, s_CleanupPollTimerID );
|
||
|
SetCursor( (HCURSOR)GetClassLongPtr( m_hwnd, GCLP_HCURSOR ) );
|
||
|
m_CleanupInProgress = false;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT Status;
|
||
|
if ( FAILED( m_CleanupTask->GetStatus( &Status ) ) )
|
||
|
return;
|
||
|
|
||
|
if ( Status == SCHED_S_TASK_RUNNING )
|
||
|
return; // Not done yet, keep checking
|
||
|
|
||
|
DWORD ExitCode;
|
||
|
Hr = m_CleanupTask->GetExitCode( &ExitCode );
|
||
|
|
||
|
if ( Hr == SCHED_S_TASK_HAS_NOT_RUN )
|
||
|
return; // The task probably hasn't run yet
|
||
|
|
||
|
if ( FAILED(Hr) )
|
||
|
{
|
||
|
// If this API fails it returns the error
|
||
|
// that MSTASK received when starting the job.
|
||
|
|
||
|
KillTimer( m_hwnd, s_CleanupPollTimerID );
|
||
|
SetCursor( (HCURSOR)GetClassLongPtr( m_hwnd, GCLP_HCURSOR ) );
|
||
|
m_CleanupInProgress = false;
|
||
|
DisplayError( IDS_CANT_START_CLEANUP, Hr );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
SYSTEMTIME MostRecentRunTime;
|
||
|
if ( FAILED( m_CleanupTask->GetMostRecentRunTime( &MostRecentRunTime ) ) )
|
||
|
return;
|
||
|
|
||
|
FILETIME MostRecentRunTimeAsFileTime;
|
||
|
|
||
|
|
||
|
if ( !SystemTimeToFileTime(&MostRecentRunTime, &MostRecentRunTimeAsFileTime ) )
|
||
|
return;
|
||
|
|
||
|
if ( CompareFileTime( &MostRecentRunTimeAsFileTime, &m_PrevCleanupStartTime ) < 0 )
|
||
|
return; // task may not have scheduled yet, keep checking
|
||
|
|
||
|
//
|
||
|
// At this point we know the following:
|
||
|
// 1. The cursor was help in the wait state for the minimum time
|
||
|
// 2. The task is not running
|
||
|
// 3. The task started sometime after our time mark
|
||
|
//
|
||
|
// So, cleanup timers and revert back to the original icon
|
||
|
//
|
||
|
|
||
|
KillTimer( m_hwnd, s_CleanupPollTimerID );
|
||
|
SetCursor( (HCURSOR)GetClassLongPtr( m_hwnd, GCLP_HCURSOR ) );
|
||
|
m_CleanupInProgress = false;
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
CPropSheetExtension::DisplayWarning(
|
||
|
UINT StringId )
|
||
|
{
|
||
|
|
||
|
WCHAR ErrorString[ MAX_PATH * 2 ];
|
||
|
WCHAR BITSSettings[ MAX_PATH ];
|
||
|
|
||
|
LoadString( g_hinst, StringId, ErrorString, MAX_PATH*2-1 );
|
||
|
LoadString( g_hinst, IDS_BITS_EXT, BITSSettings, MAX_PATH-1 );
|
||
|
|
||
|
return ( IDOK == MessageBox( m_hwnd, ErrorString, BITSSettings, MB_OKCANCEL | MB_ICONWARNING ) );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::DisplayError(
|
||
|
UINT StringId )
|
||
|
{
|
||
|
|
||
|
WCHAR ErrorString[ MAX_PATH * 2 ];
|
||
|
WCHAR BITSSettings[ MAX_PATH ];
|
||
|
|
||
|
LoadString( g_hinst, StringId, ErrorString, MAX_PATH*2-1 );
|
||
|
LoadString( g_hinst, IDS_BITS_EXT, BITSSettings, MAX_PATH-1 );
|
||
|
|
||
|
MessageBox( m_hwnd, ErrorString, BITSSettings, MB_OK | MB_ICONWARNING ) ;
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::DisplayError(
|
||
|
UINT StringId,
|
||
|
HRESULT Hr )
|
||
|
{
|
||
|
WCHAR ErrorString[ MAX_PATH * 2 ];
|
||
|
WCHAR BITSSettings[ MAX_PATH ];
|
||
|
|
||
|
LoadString( g_hinst, StringId, ErrorString, MAX_PATH*2-1 );
|
||
|
LoadString( g_hinst, IDS_BITS_EXT, BITSSettings, MAX_PATH-1 );
|
||
|
|
||
|
WCHAR * SystemMessage = NULL;
|
||
|
DWORD ReturnValue =
|
||
|
FormatMessage(
|
||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||
|
NULL,
|
||
|
(DWORD)Hr,
|
||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||
|
(LPTSTR) &SystemMessage,
|
||
|
0,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if ( !ReturnValue )
|
||
|
MessageBox( m_hwnd, ErrorString, BITSSettings, MB_OK | MB_ICONWARNING );
|
||
|
else
|
||
|
{
|
||
|
|
||
|
WCHAR CombinedErrorString[ MAX_PATH * 4 ];
|
||
|
|
||
|
StringCbPrintfW(
|
||
|
CombinedErrorString,
|
||
|
sizeof( CombinedErrorString ),
|
||
|
L"%s\r\n\r\n%s",
|
||
|
ErrorString,
|
||
|
SystemMessage );
|
||
|
|
||
|
MessageBox( m_hwnd, CombinedErrorString, BITSSettings, MB_OK | MB_ICONWARNING );
|
||
|
|
||
|
LocalFree( SystemMessage );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
CPropSheetExtension::GetDlgItemTextAsInteger(
|
||
|
UINT Id,
|
||
|
UINT MaxString,
|
||
|
UINT64 & Value )
|
||
|
{
|
||
|
|
||
|
WCHAR *DlgString = NULL;
|
||
|
WCHAR *p = NULL;
|
||
|
Value = 0;
|
||
|
|
||
|
DlgString = new WCHAR[ MaxString + 1 ];
|
||
|
|
||
|
if ( !DlgString )
|
||
|
goto failed;
|
||
|
|
||
|
GetDlgItemText( m_hwnd, Id, DlgString, MaxString );
|
||
|
|
||
|
if ( L'\0' == *DlgString )
|
||
|
return false;
|
||
|
|
||
|
int CharsRequired =
|
||
|
FoldString(
|
||
|
MAP_FOLDDIGITS,
|
||
|
DlgString,
|
||
|
-1,
|
||
|
NULL,
|
||
|
0 );
|
||
|
|
||
|
if ( !CharsRequired )
|
||
|
return false;
|
||
|
|
||
|
p = new WCHAR[ CharsRequired + 1 ];
|
||
|
|
||
|
if ( !p )
|
||
|
goto failed;
|
||
|
|
||
|
CharsRequired =
|
||
|
FoldString(
|
||
|
MAP_FOLDDIGITS,
|
||
|
DlgString,
|
||
|
-1,
|
||
|
p,
|
||
|
CharsRequired );
|
||
|
|
||
|
if ( !CharsRequired )
|
||
|
return false;
|
||
|
|
||
|
// accumulate value
|
||
|
while(L'\0' != *p )
|
||
|
{
|
||
|
|
||
|
UINT64 ExtendedValue = Value * 10;
|
||
|
if ( ExtendedValue / 10 != Value )
|
||
|
return false;
|
||
|
|
||
|
Value = ExtendedValue;
|
||
|
|
||
|
if ( *p < L'0' || *p > L'9' )
|
||
|
return false;
|
||
|
|
||
|
|
||
|
UINT64 ValueToAdd = *p - L'0';
|
||
|
|
||
|
if ( 0xFFFFFFFFFFFFFFFF - ValueToAdd < Value )
|
||
|
return false; //overflow
|
||
|
|
||
|
Value += ValueToAdd;
|
||
|
p++;
|
||
|
|
||
|
}
|
||
|
|
||
|
delete[] DlgString;
|
||
|
delete[] p;
|
||
|
|
||
|
return true;
|
||
|
|
||
|
failed:
|
||
|
|
||
|
delete[] DlgString;
|
||
|
delete[] p;
|
||
|
return false;
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::SetDlgItemTextAsInteger(
|
||
|
UINT Id,
|
||
|
UINT64 Value )
|
||
|
{
|
||
|
|
||
|
WCHAR RawString[ 25 ]; // 18446744073709551615
|
||
|
|
||
|
WCHAR *p = RawString + 25 - 1;
|
||
|
*p-- = L'\0';
|
||
|
|
||
|
if ( !Value )
|
||
|
{
|
||
|
*p = L'0';
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
do
|
||
|
{
|
||
|
UINT64 Remainder = Value % 10;
|
||
|
Value = Value / 10;
|
||
|
*p-- = ( L'0' + (WCHAR)Remainder );
|
||
|
} while( Value );
|
||
|
|
||
|
p++;
|
||
|
|
||
|
}
|
||
|
|
||
|
NUMBERFMT Format;
|
||
|
memset( &Format, 0, sizeof(Format) );
|
||
|
Format.lpDecimalSep = L"";
|
||
|
Format.lpThousandSep = L"";
|
||
|
|
||
|
int CharsRequired =
|
||
|
GetNumberFormat(
|
||
|
NULL,
|
||
|
0,
|
||
|
p,
|
||
|
&Format,
|
||
|
NULL,
|
||
|
0 );
|
||
|
|
||
|
if ( !CharsRequired )
|
||
|
return;
|
||
|
|
||
|
WCHAR *ConvertedString = new WCHAR[ CharsRequired ];
|
||
|
|
||
|
if ( !ConvertedString )
|
||
|
return;
|
||
|
|
||
|
CharsRequired =
|
||
|
GetNumberFormat(
|
||
|
NULL,
|
||
|
0,
|
||
|
p,
|
||
|
&Format,
|
||
|
ConvertedString,
|
||
|
CharsRequired );
|
||
|
|
||
|
|
||
|
if ( CharsRequired )
|
||
|
SetDlgItemText( m_hwnd, Id, ConvertedString );
|
||
|
|
||
|
delete[] ConvertedString;
|
||
|
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
CPropSheetExtension::ValidateValues( )
|
||
|
{
|
||
|
|
||
|
// Validate the maximum upload
|
||
|
|
||
|
if ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_LIMIT_MAX_UPLOAD ) )
|
||
|
{
|
||
|
|
||
|
LRESULT MaxUploadUnit = SendDlgItemMessage( m_hwnd, IDC_COMBO_MAX_UPLOAD_UNITS, CB_GETCURSEL, 0, 0 );
|
||
|
|
||
|
UINT64 MaxUpload;
|
||
|
|
||
|
if (!GetDlgItemTextAsInteger( IDC_EDIT_MAX_UPLOAD, MAX_PATH, MaxUpload ) ||
|
||
|
MaxUpload > s_MaxUploadLimits[MaxUploadUnit] )
|
||
|
{
|
||
|
DisplayError( IDS_MAX_UPLOAD_INVALID );
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Validate the session timeout
|
||
|
|
||
|
if ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_DELETE_FILES ) )
|
||
|
{
|
||
|
|
||
|
LRESULT SessionTimeoutUnit =
|
||
|
SendDlgItemMessage( m_hwnd, IDC_COMBO_SESSION_TIMEOUT_UNITS, CB_GETCURSEL, 0, 0 );
|
||
|
|
||
|
UINT64 SessionTimeout;
|
||
|
|
||
|
if ( !GetDlgItemTextAsInteger( IDC_EDIT_SESSION_TIMEOUT, MAX_PATH, SessionTimeout ) ||
|
||
|
SessionTimeout > s_TimeoutLimits[SessionTimeoutUnit] )
|
||
|
{
|
||
|
DisplayError( IDS_SESSION_TIMEOUT_INVALID );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// Validate the server farm settings
|
||
|
|
||
|
if ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_ENABLE_SERVER_FARM ) )
|
||
|
{
|
||
|
|
||
|
LRESULT HostIdLength =
|
||
|
SendDlgItemMessage( m_hwnd, IDC_EDIT_HOSTID, WM_GETTEXTLENGTH, 0, 0 );
|
||
|
|
||
|
if ( !HostIdLength )
|
||
|
{
|
||
|
DisplayError( IDS_HOST_ID_INVALID );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_FALLBACK_TIMEOUT ) )
|
||
|
{
|
||
|
|
||
|
LRESULT FallbackTimeoutUnit =
|
||
|
SendDlgItemMessage( m_hwnd, IDC_COMBO_FALLBACK_TIMEOUT_UNITS, CB_GETCURSEL, 0, 0 );
|
||
|
|
||
|
UINT64 FallbackTimeout;
|
||
|
|
||
|
if ( !GetDlgItemTextAsInteger( IDC_EDIT_FALLBACK_TIMEOUT, MAX_PATH, FallbackTimeout ) ||
|
||
|
FallbackTimeout > s_TimeoutLimits[ FallbackTimeoutUnit ] )
|
||
|
{
|
||
|
DisplayError( IDS_FALLBACK_TIMEOUT_INVALID );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// Validate the notification settings
|
||
|
|
||
|
if ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_ENABLE_NOTIFICATIONS ) )
|
||
|
{
|
||
|
|
||
|
LRESULT NotificationURLLength =
|
||
|
SendDlgItemMessage( m_hwnd, IDC_EDIT_NOTIFICATION_URL, WM_GETTEXTLENGTH, 0, 0 );
|
||
|
|
||
|
if ( !NotificationURLLength )
|
||
|
{
|
||
|
DisplayError( IDS_NOTIFICATION_URL_INVALID );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
return WarnAboutAccessFlags();
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
CPropSheetExtension::WarnAboutAccessFlags()
|
||
|
{
|
||
|
|
||
|
if ( m_EnabledSettingChanged &&
|
||
|
( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_BITS_UPLOAD ) ) )
|
||
|
{
|
||
|
|
||
|
HRESULT Hr = S_OK;
|
||
|
DWORD BufferRequired = 0;
|
||
|
DWORD AccessFlags = 0;
|
||
|
|
||
|
METADATA_RECORD mdr;
|
||
|
mdr.dwMDIdentifier = MD_ACCESS_PERM;
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = DWORD_METADATA;
|
||
|
mdr.pbMDData = (unsigned char*)&AccessFlags;
|
||
|
mdr.dwMDDataLen = sizeof( AccessFlags );
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
DisplayError( IDS_CANT_ACCESS_METABASE, Hr );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ( AccessFlags & ( MD_ACCESS_EXECUTE | MD_ACCESS_SCRIPT ) )
|
||
|
{
|
||
|
return DisplayWarning( IDS_ACCESS_PERMISSION_WARNING );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::LoadInheritedDWORD(
|
||
|
METADATA_HANDLE mdHandle,
|
||
|
WCHAR * pKeyName,
|
||
|
DWORD PropId,
|
||
|
DWORD * pReturn )
|
||
|
{
|
||
|
|
||
|
METADATA_RECORD mdr;
|
||
|
DWORD BufferRequired;
|
||
|
HRESULT Hr;
|
||
|
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( PropId );
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT | METADATA_PARTIAL_PATH;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = DWORD_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)pReturn;
|
||
|
mdr.dwMDDataLen = sizeof(*pReturn);
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
mdHandle,
|
||
|
pKeyName,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
return Hr;
|
||
|
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::LoadInheritedString(
|
||
|
METADATA_HANDLE mdHandle,
|
||
|
WCHAR * pKeyName,
|
||
|
DWORD PropId,
|
||
|
WCHAR ** pReturn )
|
||
|
{
|
||
|
|
||
|
*pReturn = NULL;
|
||
|
METADATA_RECORD mdr;
|
||
|
DWORD BufferRequired;
|
||
|
HRESULT Hr;
|
||
|
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( PropId );
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT | METADATA_PARTIAL_PATH;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = STRING_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)NULL;
|
||
|
mdr.dwMDDataLen = 0;
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
mdHandle,
|
||
|
pKeyName,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
if ( FAILED( Hr ) && HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) != Hr )
|
||
|
return Hr;
|
||
|
|
||
|
*pReturn = new WCHAR[ BufferRequired ];
|
||
|
|
||
|
if ( !*pReturn )
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
mdr.dwMDDataLen = BufferRequired;
|
||
|
mdr.pbMDData = (BYTE*)*pReturn;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
mdHandle,
|
||
|
pKeyName,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
delete *pReturn;
|
||
|
*pReturn = NULL;
|
||
|
return Hr;
|
||
|
}
|
||
|
|
||
|
return Hr;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::LoadInheritedValues()
|
||
|
{
|
||
|
|
||
|
HRESULT Hr;
|
||
|
METADATA_RECORD mdr;
|
||
|
METADATA_HANDLE mdHandle = NULL;
|
||
|
DWORD BufferRequired;
|
||
|
|
||
|
m_InheritedValues.NotificationURL = NULL;
|
||
|
m_InheritedValues.HostId = NULL;
|
||
|
|
||
|
//
|
||
|
// A huge trick is used here to obtain the inherited properties.
|
||
|
// The idea is to take a key which probably doesn't exit at the same
|
||
|
// level as the key for the virtual directory. A guid looks
|
||
|
// like a good key name to use that probably doesn't exist.
|
||
|
//
|
||
|
|
||
|
GUID guid;
|
||
|
WCHAR unusedkey[50];
|
||
|
|
||
|
CoCreateGuid( &guid );
|
||
|
StringFromGUID2( guid, unusedkey, 49 );
|
||
|
|
||
|
Hr = m_IISAdminBase->OpenKey(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabaseParent,
|
||
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
|
||
|
10000, // 10 seconds
|
||
|
&mdHandle );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
goto error;
|
||
|
|
||
|
// Load the maximum upload size
|
||
|
|
||
|
|
||
|
{
|
||
|
WCHAR *MaximumUploadSize = NULL;
|
||
|
|
||
|
if ( FAILED(
|
||
|
Hr = LoadInheritedString(
|
||
|
mdHandle,
|
||
|
unusedkey,
|
||
|
MD_BITS_MAX_FILESIZE,
|
||
|
&MaximumUploadSize ) ) )
|
||
|
goto error;
|
||
|
|
||
|
if ( wcscmp( MaximumUploadSize, MD_BITS_UNLIMITED_MAX_FILESIZE) == 0 )
|
||
|
m_InheritedValues.MaxUploadSize = MD_BITS_UNLIMITED_MAX_FILESIZE_AS_INT64;
|
||
|
else
|
||
|
swscanf( MaximumUploadSize, L"%I64u", &m_InheritedValues.MaxUploadSize );
|
||
|
|
||
|
delete MaximumUploadSize;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// Load the session timeout
|
||
|
|
||
|
if ( FAILED(
|
||
|
Hr = LoadInheritedDWORD(
|
||
|
mdHandle,
|
||
|
unusedkey,
|
||
|
MD_BITS_NO_PROGRESS_TIMEOUT,
|
||
|
&m_InheritedValues.SessionTimeout ) ) )
|
||
|
goto error;
|
||
|
|
||
|
// Load the notification settings
|
||
|
|
||
|
if ( FAILED(
|
||
|
Hr = LoadInheritedDWORD(
|
||
|
mdHandle,
|
||
|
unusedkey,
|
||
|
MD_BITS_NOTIFICATION_URL_TYPE,
|
||
|
(DWORD*)&m_InheritedValues.NotificationType ) ) )
|
||
|
goto error;
|
||
|
|
||
|
if ( FAILED(
|
||
|
Hr = LoadInheritedString(
|
||
|
mdHandle,
|
||
|
unusedkey,
|
||
|
MD_BITS_NOTIFICATION_URL,
|
||
|
&m_InheritedValues.NotificationURL ) ) )
|
||
|
goto error;
|
||
|
|
||
|
|
||
|
// Load the web farm settings
|
||
|
|
||
|
if ( FAILED(
|
||
|
Hr = LoadInheritedString(
|
||
|
mdHandle,
|
||
|
unusedkey,
|
||
|
MD_BITS_HOSTID,
|
||
|
&m_InheritedValues.HostId ) ) )
|
||
|
goto error;
|
||
|
|
||
|
if ( FAILED(
|
||
|
Hr = LoadInheritedDWORD(
|
||
|
mdHandle,
|
||
|
unusedkey,
|
||
|
MD_BITS_HOSTID_FALLBACK_TIMEOUT,
|
||
|
(DWORD*)&m_InheritedValues.FallbackTimeout ) ) )
|
||
|
goto error;
|
||
|
|
||
|
|
||
|
m_IISAdminBase->CloseKey( mdHandle );
|
||
|
mdHandle = NULL;
|
||
|
|
||
|
return;
|
||
|
|
||
|
error:
|
||
|
|
||
|
if ( mdHandle )
|
||
|
m_IISAdminBase->CloseKey( mdHandle );
|
||
|
|
||
|
// use default values
|
||
|
m_InheritedValues.MaxUploadSize = MD_DEFAULT_BITS_MAX_FILESIZE_AS_INT64;
|
||
|
m_InheritedValues.SessionTimeout = MD_DEFAULT_NO_PROGESS_TIMEOUT;
|
||
|
m_InheritedValues.NotificationType = MD_DEFAULT_BITS_NOTIFICATION_URL_TYPE;
|
||
|
|
||
|
delete m_InheritedValues.NotificationURL;
|
||
|
m_InheritedValues.NotificationURL = NULL;
|
||
|
|
||
|
delete m_InheritedValues.HostId;
|
||
|
m_InheritedValues.HostId = NULL;
|
||
|
|
||
|
DisplayError( IDS_CANT_LOAD_INHERITED_VALUES, Hr );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::LoadMaxUploadValue( UINT64 MaxValue )
|
||
|
{
|
||
|
|
||
|
if ( MaxValue == MD_BITS_UNLIMITED_MAX_FILESIZE_AS_INT64 )
|
||
|
{
|
||
|
SendDlgItemMessage(m_hwnd, IDC_COMBO_MAX_UPLOAD_UNITS, CB_SETCURSEL, 0, 0 );
|
||
|
SetDlgItemText( m_hwnd, IDC_EDIT_MAX_UPLOAD, L"" );
|
||
|
CheckDlgButton( m_hwnd, IDC_CHECK_LIMIT_MAX_UPLOAD, BST_UNCHECKED );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
int Scale = s_NumberOfMaxUploadUnitsScales-1;
|
||
|
while ( MaxValue % s_MaxUploadUnitsScales[Scale] )
|
||
|
Scale--;
|
||
|
|
||
|
|
||
|
SendDlgItemMessage(m_hwnd, IDC_COMBO_MAX_UPLOAD_UNITS, CB_SETCURSEL, Scale, 0 );
|
||
|
SetDlgItemTextAsInteger( IDC_EDIT_MAX_UPLOAD, MaxValue / s_MaxUploadUnitsScales[Scale] );
|
||
|
CheckDlgButton( m_hwnd, IDC_CHECK_LIMIT_MAX_UPLOAD, BST_CHECKED );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::LoadTimeoutValue(
|
||
|
DWORD CheckId,
|
||
|
DWORD EditId,
|
||
|
DWORD UnitId,
|
||
|
DWORD Value )
|
||
|
{
|
||
|
|
||
|
if ( MD_BITS_NO_TIMEOUT == Value )
|
||
|
{
|
||
|
SendDlgItemMessage( m_hwnd, UnitId, CB_SETCURSEL, 0, 0 );
|
||
|
SetDlgItemText( m_hwnd, EditId, L"");
|
||
|
CheckDlgButton( m_hwnd, CheckId, BST_UNCHECKED );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
int Scale = s_NumberOfTimeoutUnitsScales-1;
|
||
|
while ( Value % s_TimeoutUnitsScales[Scale] )
|
||
|
Scale--;
|
||
|
|
||
|
SendDlgItemMessage( m_hwnd, UnitId, CB_SETCURSEL, Scale, 0 );
|
||
|
SetDlgItemTextAsInteger( EditId,
|
||
|
Value / s_TimeoutUnitsScales[Scale] );
|
||
|
CheckDlgButton( m_hwnd, CheckId, BST_CHECKED );
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::LoadTimeoutValue( DWORD SessionTimeout )
|
||
|
{
|
||
|
|
||
|
LoadTimeoutValue(
|
||
|
IDC_DELETE_FILES, // check id
|
||
|
IDC_EDIT_SESSION_TIMEOUT, // edit id
|
||
|
IDC_COMBO_SESSION_TIMEOUT_UNITS, // unit id
|
||
|
SessionTimeout );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::LoadNotificationValues(
|
||
|
BITS_SERVER_NOTIFICATION_TYPE NotificationType,
|
||
|
WCHAR *NotificationURL )
|
||
|
{
|
||
|
|
||
|
if ( BITS_NOTIFICATION_TYPE_NONE == NotificationType )
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_EDIT_NOTIFICATION_URL, L"" );
|
||
|
SendDlgItemMessage( m_hwnd, IDC_COMBO_NOTIFICATION_TYPE, CB_SETCURSEL, 0, 0 );
|
||
|
CheckDlgButton( m_hwnd, IDC_CHECK_ENABLE_NOTIFICATIONS, BST_UNCHECKED );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
SendDlgItemMessage( m_hwnd, IDC_COMBO_NOTIFICATION_TYPE, CB_SETCURSEL,
|
||
|
(WPARAM)NotificationType - BITS_NOTIFICATION_TYPE_POST_BYREF, 0 );
|
||
|
SetDlgItemText( m_hwnd, IDC_EDIT_NOTIFICATION_URL, NotificationURL );
|
||
|
CheckDlgButton( m_hwnd, IDC_CHECK_ENABLE_NOTIFICATIONS, BST_CHECKED );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::LoadServerFarmSettings(
|
||
|
WCHAR *HostId,
|
||
|
DWORD FallbackTimeout )
|
||
|
{
|
||
|
|
||
|
if ( !HostId || !*HostId )
|
||
|
{
|
||
|
SetDlgItemText( m_hwnd, IDC_EDIT_HOSTID, L"" );
|
||
|
CheckDlgButton( m_hwnd, IDC_ENABLE_SERVER_FARM, BST_UNCHECKED );
|
||
|
|
||
|
LoadTimeoutValue(
|
||
|
IDC_CHECK_FALLBACK_TIMEOUT,
|
||
|
IDC_EDIT_FALLBACK_TIMEOUT,
|
||
|
IDC_COMBO_FALLBACK_TIMEOUT_UNITS,
|
||
|
FallbackTimeout );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
SetDlgItemText( m_hwnd, IDC_EDIT_HOSTID, HostId );
|
||
|
CheckDlgButton( m_hwnd, IDC_ENABLE_SERVER_FARM, BST_CHECKED );
|
||
|
|
||
|
LoadTimeoutValue(
|
||
|
IDC_CHECK_FALLBACK_TIMEOUT,
|
||
|
IDC_EDIT_FALLBACK_TIMEOUT,
|
||
|
IDC_COMBO_FALLBACK_TIMEOUT_UNITS,
|
||
|
FallbackTimeout );
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::LoadValues( )
|
||
|
{
|
||
|
|
||
|
HRESULT Hr;
|
||
|
HRESULT LastError = S_OK;
|
||
|
BOOL IsBitsEnabled = FALSE;
|
||
|
|
||
|
m_SettingsChanged = m_EnabledSettingChanged = false;
|
||
|
|
||
|
Hr = IsBITSEnabledOnVDir(
|
||
|
m_PropertyMan,
|
||
|
m_IISAdminBase,
|
||
|
m_MetabasePath,
|
||
|
&IsBitsEnabled );
|
||
|
|
||
|
if ( IsBitsEnabled )
|
||
|
CheckDlgButton( m_hwnd, IDC_CHECK_BITS_UPLOAD, BST_CHECKED );
|
||
|
else
|
||
|
CheckDlgButton( m_hwnd, IDC_CHECK_BITS_UPLOAD, BST_UNCHECKED );
|
||
|
|
||
|
if ( FAILED(Hr) )
|
||
|
LastError = Hr;
|
||
|
|
||
|
bool AllDefaults = true;
|
||
|
|
||
|
METADATA_RECORD mdr;
|
||
|
DWORD BufferRequired;
|
||
|
|
||
|
// Load the maximum upload size
|
||
|
WCHAR MaximumUploadSize[MAX_PATH];
|
||
|
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( MD_BITS_MAX_FILESIZE );
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT | METADATA_ISINHERITED;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = STRING_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)MaximumUploadSize;
|
||
|
mdr.dwMDDataLen = sizeof(MaximumUploadSize);
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
LastError = Hr;
|
||
|
LoadMaxUploadValue( m_InheritedValues.MaxUploadSize );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if ( !( mdr.dwMDAttributes & METADATA_ISINHERITED ) )
|
||
|
AllDefaults = false;
|
||
|
|
||
|
UINT64 MaximumUploadSizeInt;
|
||
|
swscanf( MaximumUploadSize, L"%I64u", &MaximumUploadSizeInt );
|
||
|
|
||
|
LoadMaxUploadValue( MaximumUploadSizeInt );
|
||
|
|
||
|
}
|
||
|
|
||
|
// Load the session timeout
|
||
|
DWORD SessionTimeout = m_InheritedValues.SessionTimeout;
|
||
|
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( MD_BITS_NO_PROGRESS_TIMEOUT );
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT | METADATA_ISINHERITED;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = DWORD_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)&SessionTimeout;
|
||
|
mdr.dwMDDataLen = sizeof(SessionTimeout);
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
LastError = Hr;
|
||
|
LoadTimeoutValue( m_InheritedValues.SessionTimeout );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if ( !( mdr.dwMDAttributes & METADATA_ISINHERITED ) )
|
||
|
AllDefaults = false;
|
||
|
|
||
|
LoadTimeoutValue( SessionTimeout );
|
||
|
}
|
||
|
|
||
|
// Load the notification settings
|
||
|
DWORD NotificationType;
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( MD_BITS_NOTIFICATION_URL_TYPE );
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT | METADATA_ISINHERITED;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = DWORD_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)&NotificationType;
|
||
|
mdr.dwMDDataLen = sizeof(NotificationType);
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
LastError = Hr;
|
||
|
LoadNotificationValues( m_InheritedValues.NotificationType, m_InheritedValues.NotificationURL );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if ( !( mdr.dwMDAttributes & METADATA_ISINHERITED ) )
|
||
|
AllDefaults = false;
|
||
|
|
||
|
if ( BITS_NOTIFICATION_TYPE_NONE == NotificationType )
|
||
|
LoadNotificationValues( BITS_NOTIFICATION_TYPE_NONE, L"" );
|
||
|
else
|
||
|
{
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( MD_BITS_NOTIFICATION_URL );
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT | METADATA_ISINHERITED;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = STRING_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)NULL;
|
||
|
mdr.dwMDDataLen = 0;
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
if ( FAILED( Hr ) && HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) != Hr )
|
||
|
{
|
||
|
LastError = Hr;
|
||
|
LoadNotificationValues( (BITS_SERVER_NOTIFICATION_TYPE)NotificationType, L"" );
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
|
||
|
BYTE *URL = new BYTE[ BufferRequired ];
|
||
|
|
||
|
if ( !URL )
|
||
|
Hr = E_OUTOFMEMORY;
|
||
|
|
||
|
mdr.dwMDDataLen = BufferRequired;
|
||
|
mdr.pbMDData = URL;
|
||
|
|
||
|
if ( BufferRequired )
|
||
|
{
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
LastError = Hr;
|
||
|
LoadNotificationValues( (BITS_SERVER_NOTIFICATION_TYPE)NotificationType, L"" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( !( mdr.dwMDAttributes & METADATA_ISINHERITED ) )
|
||
|
AllDefaults = false;
|
||
|
LoadNotificationValues( (BITS_SERVER_NOTIFICATION_TYPE)NotificationType, (WCHAR*)URL );
|
||
|
|
||
|
}
|
||
|
|
||
|
delete[] URL;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Load the HostId
|
||
|
{
|
||
|
|
||
|
WCHAR *HostIdString = m_InheritedValues.HostId;
|
||
|
DWORD FallbackTimeout = m_InheritedValues.FallbackTimeout;
|
||
|
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( MD_BITS_HOSTID_FALLBACK_TIMEOUT );
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT | METADATA_ISINHERITED;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = DWORD_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)&FallbackTimeout;
|
||
|
mdr.dwMDDataLen = sizeof( FallbackTimeout );
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
FallbackTimeout = m_InheritedValues.FallbackTimeout;
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if ( !( mdr.dwMDAttributes & METADATA_ISINHERITED ) )
|
||
|
AllDefaults = false;
|
||
|
|
||
|
}
|
||
|
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( MD_BITS_HOSTID );
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT | METADATA_ISINHERITED;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = STRING_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)NULL;
|
||
|
mdr.dwMDDataLen = 0;
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
BYTE *HostId = NULL;
|
||
|
|
||
|
if ( SUCCEEDED( Hr ) || ( Hr == HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) ) )
|
||
|
{
|
||
|
|
||
|
HostId = new BYTE[ BufferRequired ];
|
||
|
mdr.dwMDDataLen = BufferRequired;
|
||
|
mdr.pbMDData = HostId;
|
||
|
|
||
|
if ( !HostId )
|
||
|
Hr = E_OUTOFMEMORY;
|
||
|
|
||
|
else
|
||
|
{
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
if ( SUCCEEDED( Hr ) )
|
||
|
{
|
||
|
|
||
|
if ( !( mdr.dwMDAttributes & METADATA_ISINHERITED ) )
|
||
|
AllDefaults = false;
|
||
|
|
||
|
HostIdString = (WCHAR*)HostId;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LoadServerFarmSettings( HostIdString, FallbackTimeout );
|
||
|
delete[] HostId;
|
||
|
|
||
|
}
|
||
|
|
||
|
CheckDlgButton( m_hwnd, IDC_CHECK_BITS_UPLOAD, IsBitsEnabled ? BST_CHECKED : BST_UNCHECKED );
|
||
|
|
||
|
CheckRadioButton( m_hwnd, IDC_RADIO_USE_INHERITED_CONFIG, IDC_RADIO_USE_CUSTOM_CONFIG,
|
||
|
AllDefaults ? IDC_RADIO_USE_INHERITED_CONFIG : IDC_RADIO_USE_CUSTOM_CONFIG );
|
||
|
UpdateUploadGroupState( );
|
||
|
|
||
|
if ( FAILED( LastError ) )
|
||
|
DisplayError( IDS_CANT_LOAD_VALUES, LastError );
|
||
|
|
||
|
UpdateCleanupState( );
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::SaveMetadataString(
|
||
|
METADATA_HANDLE mdHandle,
|
||
|
DWORD PropId,
|
||
|
WCHAR *Value )
|
||
|
{
|
||
|
|
||
|
|
||
|
METADATA_RECORD mdr;
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( PropId );
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT;
|
||
|
mdr.dwMDUserType = m_PropertyMan->GetPropertyUserType( PropId );
|
||
|
mdr.dwMDDataType = STRING_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)Value;
|
||
|
mdr.dwMDDataLen = sizeof(WCHAR) * ( wcslen( Value ) + 1 );
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
HRESULT Hr = m_IISAdminBase->SetData(
|
||
|
mdHandle,
|
||
|
NULL,
|
||
|
&mdr );
|
||
|
|
||
|
return Hr;
|
||
|
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::SaveMetadataDWORD(
|
||
|
METADATA_HANDLE mdHandle,
|
||
|
DWORD PropId,
|
||
|
DWORD Value )
|
||
|
{
|
||
|
|
||
|
METADATA_RECORD mdr;
|
||
|
|
||
|
mdr.dwMDIdentifier = m_PropertyMan->GetPropertyMetabaseID( PropId );
|
||
|
mdr.dwMDAttributes = METADATA_INHERIT;
|
||
|
mdr.dwMDUserType = m_PropertyMan->GetPropertyUserType( PropId );
|
||
|
mdr.dwMDDataType = DWORD_METADATA;
|
||
|
mdr.pbMDData = (PBYTE)&Value;
|
||
|
mdr.dwMDDataLen = sizeof(DWORD);
|
||
|
mdr.dwMDDataTag = 0;
|
||
|
|
||
|
HRESULT Hr = m_IISAdminBase->SetData(
|
||
|
mdHandle,
|
||
|
NULL,
|
||
|
&mdr );
|
||
|
|
||
|
return Hr;
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::MergeError(
|
||
|
HRESULT Hr,
|
||
|
HRESULT * LastHr )
|
||
|
{
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
*LastHr = Hr;
|
||
|
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::SaveSimpleString(
|
||
|
METADATA_HANDLE mdHandle,
|
||
|
DWORD PropId,
|
||
|
DWORD EditId )
|
||
|
{
|
||
|
|
||
|
LRESULT StringLength =
|
||
|
SendDlgItemMessage( m_hwnd, EditId, WM_GETTEXTLENGTH, 0, 0 );
|
||
|
|
||
|
WCHAR *String = new WCHAR[ StringLength + 1 ];
|
||
|
|
||
|
if ( !String )
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
GetDlgItemText( m_hwnd, EditId, String, (DWORD)(StringLength + 1));
|
||
|
|
||
|
HRESULT Hr =
|
||
|
SaveMetadataString(
|
||
|
mdHandle,
|
||
|
PropId,
|
||
|
String );
|
||
|
|
||
|
delete[] String;
|
||
|
return Hr;
|
||
|
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::SaveTimeoutValue(
|
||
|
METADATA_HANDLE mdHandle,
|
||
|
DWORD PropId,
|
||
|
DWORD CheckId,
|
||
|
DWORD EditId,
|
||
|
DWORD UnitId )
|
||
|
{
|
||
|
|
||
|
|
||
|
if ( BST_UNCHECKED == IsDlgButtonChecked( m_hwnd, CheckId ) )
|
||
|
{
|
||
|
|
||
|
return
|
||
|
SaveMetadataDWORD(
|
||
|
mdHandle,
|
||
|
PropId,
|
||
|
MD_BITS_NO_TIMEOUT );
|
||
|
|
||
|
}
|
||
|
|
||
|
LRESULT TimeoutUnitsSelect =
|
||
|
SendDlgItemMessage( m_hwnd, UnitId, CB_GETCURSEL, 0, 0 );
|
||
|
|
||
|
UINT64 Timeout64;
|
||
|
GetDlgItemTextAsInteger( EditId, MAX_PATH, Timeout64 );
|
||
|
Timeout64 *= s_TimeoutUnitsScales[ TimeoutUnitsSelect ];
|
||
|
DWORD Timeout = (DWORD)Timeout64;
|
||
|
|
||
|
return
|
||
|
SaveMetadataDWORD(
|
||
|
mdHandle,
|
||
|
PropId,
|
||
|
Timeout );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
CPropSheetExtension::SetValues( )
|
||
|
{
|
||
|
|
||
|
HRESULT Hr;
|
||
|
HRESULT LastError = S_OK;
|
||
|
METADATA_HANDLE mdHandle = NULL;
|
||
|
|
||
|
if ( m_EnabledSettingChanged )
|
||
|
{
|
||
|
|
||
|
UINT BitsUploadButton = IsDlgButtonChecked( m_hwnd, IDC_CHECK_BITS_UPLOAD );
|
||
|
|
||
|
if ( BST_CHECKED == BitsUploadButton )
|
||
|
{
|
||
|
Hr = m_IBITSSetup->EnableBITSUploads();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Hr = m_IBITSSetup->DisableBITSUploads();
|
||
|
}
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
LastError = Hr;
|
||
|
goto error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
Hr = m_IISAdminBase->OpenKey(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
|
||
|
10000, // 10 seconds
|
||
|
&mdHandle );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
{
|
||
|
LastError = Hr;
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
|
||
|
if ( BST_CHECKED == IsDlgButtonChecked( m_hwnd, IDC_RADIO_USE_INHERITED_CONFIG ) )
|
||
|
{
|
||
|
|
||
|
// delete all the configuration properties
|
||
|
|
||
|
DWORD IdsToDelete[] =
|
||
|
{
|
||
|
MD_BITS_MAX_FILESIZE,
|
||
|
MD_BITS_NO_PROGRESS_TIMEOUT,
|
||
|
MD_BITS_NOTIFICATION_URL_TYPE,
|
||
|
MD_BITS_NOTIFICATION_URL,
|
||
|
MD_BITS_HOSTID,
|
||
|
MD_BITS_HOSTID_FALLBACK_TIMEOUT
|
||
|
};
|
||
|
|
||
|
for ( DWORD i=0; i < ( sizeof(IdsToDelete) / sizeof(*IdsToDelete) ); i++ )
|
||
|
{
|
||
|
|
||
|
Hr = m_IISAdminBase->DeleteData(
|
||
|
mdHandle,
|
||
|
NULL,
|
||
|
m_PropertyMan->GetPropertyMetabaseID( IdsToDelete[i] ),
|
||
|
ALL_METADATA );
|
||
|
|
||
|
if ( FAILED( Hr ) && Hr != HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND ) &&
|
||
|
Hr != MD_ERROR_DATA_NOT_FOUND )
|
||
|
LastError = Hr;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
|
||
|
|
||
|
{
|
||
|
|
||
|
// save the maximum upload size
|
||
|
WCHAR MaxUploadSizeString[ MAX_PATH ];
|
||
|
|
||
|
LRESULT MaxUploadUnitsSelect =
|
||
|
SendDlgItemMessage( m_hwnd, IDC_COMBO_MAX_UPLOAD_UNITS, CB_GETCURSEL, 0, 0 );
|
||
|
|
||
|
if ( BST_UNCHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_LIMIT_MAX_UPLOAD ) )
|
||
|
{
|
||
|
StringCchCopyW( MaxUploadSizeString, MAX_PATH, MD_BITS_UNLIMITED_MAX_FILESIZE );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
UINT64 MaxUploadSize;
|
||
|
GetDlgItemTextAsInteger( IDC_EDIT_MAX_UPLOAD, MAX_PATH, MaxUploadSize );
|
||
|
MaxUploadSize *= s_MaxUploadUnitsScales[ MaxUploadUnitsSelect ];
|
||
|
StringCchPrintfW( MaxUploadSizeString, MAX_PATH, L"%I64u", MaxUploadSize );
|
||
|
}
|
||
|
|
||
|
MergeError(
|
||
|
SaveMetadataString(
|
||
|
mdHandle,
|
||
|
MD_BITS_MAX_FILESIZE,
|
||
|
MaxUploadSizeString ), &LastError );
|
||
|
}
|
||
|
|
||
|
MergeError(
|
||
|
SaveTimeoutValue(
|
||
|
mdHandle,
|
||
|
MD_BITS_NO_PROGRESS_TIMEOUT,
|
||
|
IDC_DELETE_FILES,
|
||
|
IDC_EDIT_SESSION_TIMEOUT,
|
||
|
IDC_COMBO_SESSION_TIMEOUT_UNITS ), &LastError );
|
||
|
|
||
|
// Save the notification settings
|
||
|
|
||
|
if ( BST_UNCHECKED == IsDlgButtonChecked( m_hwnd, IDC_CHECK_ENABLE_NOTIFICATIONS ) )
|
||
|
{
|
||
|
|
||
|
MergeError(
|
||
|
SaveMetadataDWORD(
|
||
|
mdHandle,
|
||
|
MD_BITS_NOTIFICATION_URL_TYPE,
|
||
|
BITS_NOTIFICATION_TYPE_NONE ), &LastError );
|
||
|
|
||
|
MergeError(
|
||
|
SaveMetadataString(
|
||
|
mdHandle,
|
||
|
MD_BITS_NOTIFICATION_URL,
|
||
|
L"" ), &LastError );
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
LRESULT NotificationTypeSelect =
|
||
|
SendDlgItemMessage( m_hwnd, IDC_COMBO_NOTIFICATION_TYPE, CB_GETCURSEL, 0, 0 );
|
||
|
|
||
|
BITS_SERVER_NOTIFICATION_TYPE NotificationType =
|
||
|
(BITS_SERVER_NOTIFICATION_TYPE)( NotificationTypeSelect + BITS_NOTIFICATION_TYPE_POST_BYREF );
|
||
|
|
||
|
MergeError(
|
||
|
SaveMetadataDWORD(
|
||
|
mdHandle,
|
||
|
MD_BITS_NOTIFICATION_URL_TYPE,
|
||
|
NotificationType ), &LastError );
|
||
|
|
||
|
MergeError(
|
||
|
SaveSimpleString(
|
||
|
mdHandle,
|
||
|
MD_BITS_NOTIFICATION_URL,
|
||
|
IDC_EDIT_NOTIFICATION_URL ), &LastError );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// Save the webfarm settings
|
||
|
if ( BST_UNCHECKED == IsDlgButtonChecked( m_hwnd, IDC_ENABLE_SERVER_FARM ) )
|
||
|
{
|
||
|
|
||
|
MergeError(
|
||
|
SaveMetadataString(
|
||
|
mdHandle,
|
||
|
MD_BITS_HOSTID,
|
||
|
L"" ), &LastError );
|
||
|
|
||
|
MergeError(
|
||
|
SaveMetadataDWORD(
|
||
|
mdHandle,
|
||
|
MD_BITS_HOSTID_FALLBACK_TIMEOUT,
|
||
|
MD_BITS_NO_TIMEOUT ), &LastError );
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
MergeError(
|
||
|
SaveSimpleString(
|
||
|
mdHandle,
|
||
|
MD_BITS_HOSTID,
|
||
|
IDC_EDIT_HOSTID ), &LastError );
|
||
|
|
||
|
MergeError(
|
||
|
SaveTimeoutValue(
|
||
|
mdHandle,
|
||
|
MD_BITS_HOSTID_FALLBACK_TIMEOUT,
|
||
|
IDC_CHECK_FALLBACK_TIMEOUT,
|
||
|
IDC_EDIT_FALLBACK_TIMEOUT,
|
||
|
IDC_COMBO_FALLBACK_TIMEOUT_UNITS ), &LastError );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
error:
|
||
|
|
||
|
if ( mdHandle )
|
||
|
m_IISAdminBase->CloseKey( mdHandle );
|
||
|
|
||
|
mdHandle = NULL;
|
||
|
|
||
|
if ( FAILED( LastError ) )
|
||
|
DisplayError( IDS_CANT_SAVE_VALUES, LastError );
|
||
|
|
||
|
}
|
||
|
|
||
|
void CPropSheetExtension::DisplayHelp( )
|
||
|
{
|
||
|
|
||
|
WCHAR HelpTopic[MAX_PATH];
|
||
|
LoadString( g_hinst, IDS_HELPFILE, HelpTopic, MAX_PATH-1);
|
||
|
|
||
|
HtmlHelp( NULL,
|
||
|
HelpTopic,
|
||
|
HH_DISPLAY_TOPIC,
|
||
|
0 );
|
||
|
|
||
|
}
|
||
|
|
||
|
INT_PTR CPropSheetExtension::DialogProc(
|
||
|
UINT uMsg, // message
|
||
|
WPARAM wParam, // first message parameter
|
||
|
LPARAM lParam // second message parameter
|
||
|
)
|
||
|
{
|
||
|
|
||
|
switch (uMsg) {
|
||
|
|
||
|
case WM_SETCURSOR:
|
||
|
if ( m_CleanupInProgress )
|
||
|
{
|
||
|
// set the cursor for this dialog and its children.
|
||
|
SetCursor( m_CleanupCursor );
|
||
|
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, TRUE );
|
||
|
return TRUE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_TIMER:
|
||
|
CleanupTimer( (UINT)wParam );
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_INITDIALOG:
|
||
|
|
||
|
SendDlgItemMessage( m_hwnd, IDC_EDIT_SESSION_DIRECTORY, EM_LIMITTEXT, MAX_PATH-1, 0 );
|
||
|
AddComboBoxItems( IDC_COMBO_MAX_UPLOAD_UNITS,
|
||
|
&s_MaxUploadUnits[0], s_NumberOfMaxUploadUnits );
|
||
|
AddComboBoxItems( IDC_COMBO_SESSION_TIMEOUT_UNITS,
|
||
|
&s_TimeoutUnits[0], s_NumberOfTimeoutUnits );
|
||
|
AddComboBoxItems( IDC_COMBO_NOTIFICATION_TYPE,
|
||
|
&s_NotificationTypes[0], s_NumberOfNotificationTypes );
|
||
|
AddComboBoxItems( IDC_COMBO_FALLBACK_TIMEOUT_UNITS,
|
||
|
&s_TimeoutUnits[0], s_NumberOfTimeoutUnits );
|
||
|
|
||
|
LoadInheritedValues();
|
||
|
LoadValues( );
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
if ( HIWORD(wParam) == EN_CHANGE ||
|
||
|
HIWORD(wParam) == CBN_SELCHANGE )
|
||
|
{
|
||
|
m_SettingsChanged = true;
|
||
|
SendMessage(GetParent(m_hwnd), PSM_CHANGED, (WPARAM)m_hwnd, 0);
|
||
|
}
|
||
|
|
||
|
else if ( HIWORD(wParam) == BN_CLICKED )
|
||
|
{
|
||
|
|
||
|
WORD ButtonID = LOWORD(wParam);
|
||
|
|
||
|
if ( IDC_BUTTON_SCHEDULE_CLEANUP != ButtonID &&
|
||
|
IDC_BUTTON_CLEANUP_NOW != ButtonID )
|
||
|
{
|
||
|
m_SettingsChanged = true;
|
||
|
SendMessage(GetParent(m_hwnd), PSM_CHANGED, (WPARAM)m_hwnd, 0);
|
||
|
}
|
||
|
|
||
|
switch( LOWORD(wParam) )
|
||
|
{
|
||
|
case IDC_CHECK_BITS_UPLOAD:
|
||
|
m_EnabledSettingChanged = true;
|
||
|
UpdateUploadGroupState( );
|
||
|
break;
|
||
|
|
||
|
case IDC_RADIO_USE_INHERITED_CONFIG:
|
||
|
LoadMaxUploadValue( m_InheritedValues.MaxUploadSize );
|
||
|
LoadTimeoutValue( m_InheritedValues.SessionTimeout );
|
||
|
LoadServerFarmSettings( m_InheritedValues.HostId, m_InheritedValues.FallbackTimeout );
|
||
|
LoadNotificationValues( m_InheritedValues.NotificationType,
|
||
|
m_InheritedValues.NotificationURL );
|
||
|
|
||
|
// Intentional fallthrough
|
||
|
case IDC_RADIO_USE_CUSTOM_CONFIG:
|
||
|
UpdateConfigGroupState( true );
|
||
|
break;
|
||
|
|
||
|
case IDC_CHECK_LIMIT_MAX_UPLOAD:
|
||
|
UpdateMaxUploadGroupState( true );
|
||
|
break;
|
||
|
|
||
|
case IDC_DELETE_FILES:
|
||
|
UpdateTimeoutGroupState( true );
|
||
|
break;
|
||
|
|
||
|
case IDC_CHECK_ENABLE_NOTIFICATIONS:
|
||
|
UpdateNotificationsGroupState( true );
|
||
|
break;
|
||
|
|
||
|
case IDC_ENABLE_SERVER_FARM:
|
||
|
UpdateServerFarmGroupState( true );
|
||
|
break;
|
||
|
|
||
|
case IDC_CHECK_FALLBACK_TIMEOUT:
|
||
|
UpdateServerFarmFallbackGroupState( true );
|
||
|
break;
|
||
|
|
||
|
case IDC_BUTTON_SCHEDULE_CLEANUP:
|
||
|
ScheduleCleanup();
|
||
|
break;
|
||
|
|
||
|
case IDC_BUTTON_CLEANUP_NOW:
|
||
|
CleanupNow();
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
// we don't free the notify handle for property sheets
|
||
|
// MMCFreeNotifyHandle(pThis->m_ppHandle);
|
||
|
break;
|
||
|
|
||
|
case WM_NOTIFY:
|
||
|
switch (((NMHDR *) lParam)->code)
|
||
|
{
|
||
|
|
||
|
case PSN_KILLACTIVE:
|
||
|
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, !ValidateValues( ) );
|
||
|
return TRUE;
|
||
|
|
||
|
case PSN_APPLY:
|
||
|
// don't notify the primary snap-in that Apply
|
||
|
// has been hit...
|
||
|
// MMCPropertyChangeNotify(pThis->m_ppHandle, (long)pThis);
|
||
|
|
||
|
if ( m_SettingsChanged )
|
||
|
{
|
||
|
CloseCleanupItems();
|
||
|
SetValues( );
|
||
|
UpdateCleanupState( );
|
||
|
|
||
|
// all changes are flushed now
|
||
|
m_SettingsChanged = m_EnabledSettingChanged = false;
|
||
|
}
|
||
|
|
||
|
SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, PSNRET_NOERROR );
|
||
|
return TRUE;
|
||
|
|
||
|
case PSN_HELP:
|
||
|
DisplayHelp( );
|
||
|
return TRUE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_HELP:
|
||
|
DisplayHelp( );
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::ComputeMetabaseParent()
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// Hack the metabase path to get the key parent
|
||
|
//
|
||
|
|
||
|
SIZE_T MetabaseParentSize = wcslen( m_MetabasePath ) + 1;
|
||
|
m_MetabaseParent = new WCHAR[ MetabaseParentSize ];
|
||
|
|
||
|
if ( !m_MetabaseParent )
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
StringCchCopy( m_MetabaseParent, MetabaseParentSize, m_MetabasePath );
|
||
|
|
||
|
{
|
||
|
|
||
|
WCHAR *p = m_MetabaseParent + wcslen( m_MetabaseParent );
|
||
|
while( ( L'/' != *p ) && ( p != m_MetabaseParent ) )
|
||
|
p--;
|
||
|
|
||
|
*p = L'\0';
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::ComputeUNCComputerName()
|
||
|
{
|
||
|
|
||
|
//
|
||
|
//
|
||
|
// The task scheduler expects the name of the computer to have
|
||
|
// double slashes in front of it just like UNC names. Do the
|
||
|
// conversion here.
|
||
|
//
|
||
|
SIZE_T ComputerNameSize = wcslen( m_ComputerName );
|
||
|
m_UNCComputerName = new WCHAR[ ComputerNameSize + 3 ]; // add
|
||
|
|
||
|
if ( !m_UNCComputerName )
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
WCHAR *StringDest;
|
||
|
|
||
|
if ( L'\\' == m_ComputerName[0] )
|
||
|
{
|
||
|
|
||
|
if ( L'\\' == m_ComputerName[1] )
|
||
|
{
|
||
|
// No slashes are needed
|
||
|
StringDest = m_UNCComputerName;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// need one slash
|
||
|
m_UNCComputerName[0] = L'\\';
|
||
|
StringDest = m_UNCComputerName + 1;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// need two slashes
|
||
|
m_UNCComputerName[0] = m_UNCComputerName[1] = L'\\';
|
||
|
StringDest = m_UNCComputerName + 2;
|
||
|
}
|
||
|
|
||
|
memcpy( StringDest, m_ComputerName, ( ComputerNameSize + 1 ) * sizeof( WCHAR ) );
|
||
|
|
||
|
return S_OK;
|
||
|
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CPropSheetExtension::OpenSetupInterface()
|
||
|
{
|
||
|
|
||
|
HRESULT Hr;
|
||
|
WCHAR *ADSIPath = NULL;
|
||
|
WCHAR *ConvertedMetabasePath = m_MetabasePath;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
|
||
|
if ( _wcsnicmp( m_MetabasePath, L"/LM/", wcslen(L"/LM/") ) == 0 ||
|
||
|
_wcsnicmp( m_MetabasePath, L"LM/", wcslen(L"LM/" ) ) == 0 )
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// Only do the fixup if we're not managing the local computer
|
||
|
//
|
||
|
|
||
|
WCHAR ComputerName[ MAX_COMPUTERNAME_LENGTH + 1 ];
|
||
|
|
||
|
DWORD BufferLength = MAX_COMPUTERNAME_LENGTH + 1;
|
||
|
if ( !GetComputerName( ComputerName, &BufferLength ) )
|
||
|
return HRESULT_FROM_WIN32( GetLastError() );
|
||
|
|
||
|
if ( _wcsicmp( m_ComputerName, ComputerName ) != 0 )
|
||
|
{
|
||
|
|
||
|
SIZE_T ConvertedPathSize = wcslen( m_ComputerName ) + wcslen( m_MetabasePath ) + 1;
|
||
|
ConvertedMetabasePath = new WCHAR[ ConvertedPathSize ];
|
||
|
|
||
|
if ( !ConvertedMetabasePath )
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
StringCchCopyW( ConvertedMetabasePath, ConvertedPathSize, L"/" );
|
||
|
StringCchCatW( ConvertedMetabasePath, ConvertedPathSize, m_ComputerName );
|
||
|
size_t MetabaseOffset =
|
||
|
m_MetabasePath[0] == L'/' ?
|
||
|
wcslen(L"/LM") : wcslen( L"LM" );
|
||
|
StringCchCatW( ConvertedMetabasePath, ConvertedPathSize, m_MetabasePath + MetabaseOffset );
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
ADSIPath = ConvertObjectPathToADSI( ConvertedMetabasePath );
|
||
|
THROW_COMERROR( ADsGetObject( ADSIPath, __uuidof(*m_IBITSSetup), (void**)&m_IBITSSetup ) );
|
||
|
|
||
|
if ( ConvertedMetabasePath != m_MetabasePath)
|
||
|
delete[] ConvertedMetabasePath;
|
||
|
|
||
|
ConvertedMetabasePath = NULL;
|
||
|
delete ADSIPath;
|
||
|
ADSIPath = NULL;
|
||
|
|
||
|
}
|
||
|
catch( ComError Error )
|
||
|
{
|
||
|
delete ADSIPath;
|
||
|
|
||
|
if ( ConvertedMetabasePath != m_MetabasePath )
|
||
|
delete[] ConvertedMetabasePath;
|
||
|
|
||
|
return Error.m_Hr;
|
||
|
}
|
||
|
return S_OK;
|
||
|
|
||
|
}
|
||
|
|
||
|
///////////////////////////////
|
||
|
// Interface IExtendPropertySheet
|
||
|
///////////////////////////////
|
||
|
HRESULT CPropSheetExtension::CreatePropertyPages(
|
||
|
/* [in] */ LPPROPERTYSHEETCALLBACK lpProvider,
|
||
|
/* [in] */ LONG_PTR handle,
|
||
|
/* [in] */ LPDATAOBJECT lpIDataObject)
|
||
|
{
|
||
|
|
||
|
HRESULT Hr = E_FAIL;
|
||
|
|
||
|
Hr = ExtractSnapInString( (IDataObject*)lpIDataObject, m_MetabasePath, s_cfSnapInMetapath );
|
||
|
|
||
|
if ( FAILED(Hr) )
|
||
|
return Hr;
|
||
|
|
||
|
Hr = ExtractSnapInString( (IDataObject*)lpIDataObject, m_ComputerName, s_cfSnapInMachineName );
|
||
|
|
||
|
if ( FAILED(Hr) )
|
||
|
return Hr;
|
||
|
|
||
|
Hr = ComputeUNCComputerName();
|
||
|
|
||
|
if ( FAILED(Hr) )
|
||
|
return Hr;
|
||
|
|
||
|
Hr = ExtractSnapInGUID( (IDataObject*)lpIDataObject, m_NodeGuid, s_cfNodeType );
|
||
|
|
||
|
if ( FAILED(Hr) )
|
||
|
return Hr;
|
||
|
|
||
|
Hr = ComputeMetabaseParent();
|
||
|
|
||
|
if ( FAILED(Hr) )
|
||
|
return Hr;
|
||
|
|
||
|
Hr = OpenSetupInterface();
|
||
|
|
||
|
if ( FAILED(Hr) )
|
||
|
return Hr;
|
||
|
|
||
|
|
||
|
if ( !m_IISAdminBase )
|
||
|
{
|
||
|
|
||
|
COSERVERINFO coinfo;
|
||
|
coinfo.dwReserved1 = 0;
|
||
|
coinfo.dwReserved2 = 0;
|
||
|
coinfo.pAuthInfo = NULL;
|
||
|
coinfo.pwszName = m_ComputerName;
|
||
|
|
||
|
GUID guid = __uuidof( IMSAdminBase );
|
||
|
MULTI_QI mqi;
|
||
|
mqi.hr = S_OK;
|
||
|
mqi.pIID = &guid;
|
||
|
mqi.pItf = NULL;
|
||
|
|
||
|
Hr =
|
||
|
CoCreateInstanceEx(
|
||
|
GETAdminBaseCLSID(TRUE),
|
||
|
NULL,
|
||
|
CLSCTX_SERVER,
|
||
|
&coinfo,
|
||
|
1,
|
||
|
&mqi );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
return Hr;
|
||
|
|
||
|
if ( FAILED( mqi.hr ) )
|
||
|
return mqi.hr;
|
||
|
|
||
|
m_IISAdminBase = (IMSAdminBase*)mqi.pItf;
|
||
|
|
||
|
}
|
||
|
|
||
|
METADATA_RECORD mdr;
|
||
|
DWORD BufferRequired;
|
||
|
memset( &mdr, 0, sizeof(mdr) );
|
||
|
|
||
|
mdr.dwMDIdentifier = MD_KEY_TYPE;
|
||
|
mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
||
|
mdr.dwMDUserType = ALL_METADATA;
|
||
|
mdr.dwMDDataType = ALL_METADATA;
|
||
|
mdr.dwMDDataLen = sizeof(m_NodeTypeName);
|
||
|
mdr.pbMDData = (PBYTE) m_NodeTypeName;
|
||
|
|
||
|
Hr = m_IISAdminBase->GetData(
|
||
|
METADATA_MASTER_ROOT_HANDLE,
|
||
|
m_MetabasePath,
|
||
|
&mdr,
|
||
|
&BufferRequired );
|
||
|
|
||
|
// Out of buffer isn't really an error, its just that the
|
||
|
// node type is bigger then what we are looking for.
|
||
|
if ( Hr == HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) )
|
||
|
return S_FALSE;
|
||
|
|
||
|
if ( FAILED(Hr) )
|
||
|
return Hr;
|
||
|
|
||
|
// Do not display pages for nodes that are not virtual directories
|
||
|
if ( 0 != wcscmp( L"IIsWebVirtualDir", m_NodeTypeName ) )
|
||
|
return S_FALSE;
|
||
|
|
||
|
// Create property manager
|
||
|
|
||
|
m_PropertyMan = new PropertyIDManager();
|
||
|
|
||
|
if ( !m_PropertyMan )
|
||
|
return E_OUTOFMEMORY;
|
||
|
|
||
|
Hr = m_PropertyMan->LoadPropertyInfo( m_ComputerName );
|
||
|
|
||
|
if ( FAILED( Hr ) )
|
||
|
return Hr;
|
||
|
|
||
|
PROPSHEETPAGE psp;
|
||
|
HPROPSHEETPAGE hPage = NULL;
|
||
|
|
||
|
// we don't cache this handle like in a primary snap-in
|
||
|
// the handle value here is always 0
|
||
|
// m_ppHandle = handle;
|
||
|
|
||
|
|
||
|
memset( &psp, 0, sizeof(psp) );
|
||
|
psp.dwSize = sizeof(PROPSHEETPAGE);
|
||
|
psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HASHELP;
|
||
|
psp.hInstance = g_hinst;
|
||
|
psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_LARGE);
|
||
|
psp.pfnDlgProc = DialogProcExternal;
|
||
|
psp.lParam = reinterpret_cast<LPARAM>(this);
|
||
|
psp.pszTitle = MAKEINTRESOURCE(IDS_BITS_EXT);
|
||
|
|
||
|
hPage = CreatePropertySheetPage(&psp);
|
||
|
_ASSERT(hPage);
|
||
|
|
||
|
Hr = lpProvider->AddPage(hPage);
|
||
|
return Hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CPropSheetExtension::QueryPagesFor(
|
||
|
/* [in] */ LPDATAOBJECT lpDataObject)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
void * _cdecl ::operator new( size_t Size )
|
||
|
{
|
||
|
return HeapAlloc( GetProcessHeap(), 0, Size );
|
||
|
}
|
||
|
|
||
|
void _cdecl ::operator delete( void *Memory )
|
||
|
{
|
||
|
if ( !Memory )
|
||
|
return;
|
||
|
|
||
|
HeapFree( GetProcessHeap(), 0, Memory );
|
||
|
}
|
||
|
|