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.
1178 lines
30 KiB
1178 lines
30 KiB
// VirtualRoot.cpp : Implementation of CNntpVirtualRoot & CNntpVirtualRoots.
|
|
|
|
#include "stdafx.h"
|
|
#include "nntpcmn.h"
|
|
#include "cmultisz.h"
|
|
#include "vroots.h"
|
|
#include "oleutil.h"
|
|
#include "metautil.h"
|
|
#include "metakey.h"
|
|
|
|
#define THIS_FILE_HELP_CONTEXT 0
|
|
#define THIS_FILE_PROG_ID _T("Nntpadm.VirtualServer.1")
|
|
#define THIS_FILE_IID IID_INntpVirtualServer
|
|
|
|
#define DEFAULT_ACCESS_PERM ( 0 )
|
|
|
|
CVRoot::CVRoot () :
|
|
m_dwWin32Error ( 0 ),
|
|
m_bvAccess ( 0 ),
|
|
m_bvSslAccess ( 0 ),
|
|
m_fLogAccess ( TRUE ),
|
|
m_fIndexContent ( TRUE ),
|
|
m_dwUseAccount ( 0 ),
|
|
m_fDoExpire ( FALSE ),
|
|
m_fOwnModerator ( FALSE )
|
|
{
|
|
}
|
|
|
|
HRESULT CVRoot::SetProperties (
|
|
BSTR strNewsgroupSubtree,
|
|
BSTR strDirectory,
|
|
DWORD dwWin32Error,
|
|
DWORD bvAccess,
|
|
DWORD bvSslAccess,
|
|
BOOL fLogAccess,
|
|
BOOL fIndexContent,
|
|
BSTR strUNCUsername,
|
|
BSTR strUNCPassword,
|
|
BSTR strDriverProgId,
|
|
BSTR strGroupPropFile,
|
|
DWORD dwUseAccount,
|
|
BOOL fDoExpire,
|
|
BOOL fOwnModerator,
|
|
BSTR strMdbGuid
|
|
)
|
|
{
|
|
_ASSERT ( IS_VALID_STRING ( strNewsgroupSubtree ) );
|
|
_ASSERT ( IS_VALID_STRING ( strDirectory ) );
|
|
_ASSERT ( IS_VALID_STRING ( strUNCUsername ) );
|
|
_ASSERT ( IS_VALID_STRING ( strUNCPassword ) );
|
|
_ASSERT ( IS_VALID_STRING ( strDriverProgId ) );
|
|
_ASSERT ( IS_VALID_STRING ( strGroupPropFile ) );
|
|
_ASSERT ( IS_VALID_STRING ( strMdbGuid ) );
|
|
|
|
m_strNewsgroupSubtree = strNewsgroupSubtree;
|
|
m_strDirectory = strDirectory;
|
|
m_dwWin32Error = dwWin32Error;
|
|
m_bvAccess = bvAccess;
|
|
m_bvSslAccess = bvSslAccess;
|
|
m_fLogAccess = fLogAccess;
|
|
m_fIndexContent = fIndexContent;
|
|
m_strUNCUsername = strUNCUsername;
|
|
m_strUNCPassword = strUNCPassword;
|
|
m_strDriverProgId = strDriverProgId;
|
|
m_strGroupPropFile = strGroupPropFile;
|
|
m_dwUseAccount = dwUseAccount;
|
|
m_fDoExpire = fDoExpire;
|
|
m_fOwnModerator = fOwnModerator,
|
|
m_strMdbGuid = strMdbGuid;
|
|
|
|
if ( !m_strNewsgroupSubtree || !m_strDirectory || !m_strUNCUsername || !m_strUNCPassword ) {
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT CVRoot::SetProperties ( INntpVirtualRoot * pVirtualRoot )
|
|
{
|
|
HRESULT hr;
|
|
|
|
BOOL fAllowPosting;
|
|
BOOL fRestrictVisibility;
|
|
BOOL fRequireSsl;
|
|
BOOL fRequire128BitSsl;
|
|
|
|
m_strDirectory.Empty ();
|
|
m_strUNCUsername.Empty ();
|
|
m_strUNCPassword.Empty ();
|
|
m_strDriverProgId.Empty();
|
|
m_strGroupPropFile.Empty();
|
|
m_strMdbGuid.Empty();
|
|
|
|
hr = pVirtualRoot->get_NewsgroupSubtree ( &m_strNewsgroupSubtree );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pVirtualRoot->get_Directory ( &m_strDirectory );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pVirtualRoot->get_Win32Error ( (long *) &m_dwWin32Error );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pVirtualRoot->get_UNCUsername ( &m_strUNCUsername );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pVirtualRoot->get_UNCPassword ( &m_strUNCPassword );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pVirtualRoot->get_DriverProgId ( &m_strDriverProgId );
|
|
BAIL_ON_FAILURE( hr );
|
|
|
|
hr = pVirtualRoot->get_GroupPropFile ( &m_strGroupPropFile );
|
|
BAIL_ON_FAILURE( hr );
|
|
|
|
hr = pVirtualRoot->get_MdbGuid ( &m_strMdbGuid );
|
|
BAIL_ON_FAILURE( hr );
|
|
|
|
hr = pVirtualRoot->get_UseAccount( &m_dwUseAccount );
|
|
BAIL_ON_FAILURE( hr );
|
|
|
|
hr = pVirtualRoot->get_OwnExpire( &m_fDoExpire );
|
|
BAIL_ON_FAILURE( hr );
|
|
|
|
hr = pVirtualRoot->get_OwnModerator( &m_fOwnModerator );
|
|
BAIL_ON_FAILURE( hr );
|
|
|
|
hr = pVirtualRoot->get_LogAccess ( &m_fLogAccess );
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
|
|
hr = pVirtualRoot->get_IndexContent ( &m_fIndexContent );
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
|
|
|
|
hr = pVirtualRoot->get_AllowPosting ( &fAllowPosting );
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
|
|
hr = pVirtualRoot->get_RestrictGroupVisibility ( &fRestrictVisibility );
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
|
|
hr = pVirtualRoot->get_RequireSsl ( &fRequireSsl );
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
|
|
hr = pVirtualRoot->get_Require128BitSsl ( &fRequire128BitSsl );
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
|
|
SetBitFlag ( &m_bvAccess, MD_ACCESS_ALLOW_POSTING, fAllowPosting );
|
|
SetBitFlag ( &m_bvAccess, MD_ACCESS_RESTRICT_VISIBILITY, fRestrictVisibility );
|
|
|
|
SetBitFlag ( &m_bvSslAccess, MD_ACCESS_SSL, fRequireSsl );
|
|
SetBitFlag ( &m_bvSslAccess, MD_ACCESS_SSL128, fRequire128BitSsl );
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CVRoot::GetFromMetabase ( CMetabaseKey * pMB,
|
|
LPCWSTR wszName,
|
|
DWORD dwInstanceId,
|
|
LPWSTR wszServerName )
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
DWORD dwDontLog = TRUE;
|
|
|
|
m_strDirectory.Empty();
|
|
m_strUNCUsername.Empty();
|
|
m_strUNCPassword.Empty();
|
|
|
|
StdGetMetabaseProp ( pMB, MD_ACCESS_PERM, 0, &m_bvAccess, wszName );
|
|
StdGetMetabaseProp ( pMB, MD_SSL_ACCESS_PERM, 0, &m_bvSslAccess, wszName );
|
|
StdGetMetabaseProp ( pMB, MD_DONT_LOG, FALSE, &dwDontLog, wszName );
|
|
StdGetMetabaseProp ( pMB, MD_IS_CONTENT_INDEXED, FALSE, &m_fIndexContent, wszName, IIS_MD_UT_FILE);
|
|
StdGetMetabaseProp ( pMB, MD_VR_PATH, _T(""), &m_strDirectory, wszName );
|
|
//StdGetMetabaseProp ( pMB, MD_WIN32_ERROR, 0, &m_dwWin32Error, wszName, IIS_MD_UT_FILE, METADATA_NO_ATTRIBUTES );
|
|
StdGetMetabaseProp ( pMB, MD_VR_USERNAME, _T(""), &m_strUNCUsername, wszName );
|
|
StdGetMetabaseProp ( pMB, MD_VR_PASSWORD, _T(""), &m_strUNCPassword, wszName, IIS_MD_UT_SERVER, METADATA_SECURE );
|
|
StdGetMetabaseProp ( pMB, MD_VR_USE_ACCOUNT, 0, &m_dwUseAccount, wszName );
|
|
StdGetMetabaseProp ( pMB, MD_VR_DO_EXPIRE, FALSE, &m_fDoExpire, wszName );
|
|
StdGetMetabaseProp ( pMB, MD_VR_OWN_MODERATOR, FALSE, &m_fOwnModerator, wszName );
|
|
StdGetMetabaseProp ( pMB, MD_VR_DRIVER_PROGID, _T("NNTP.FSPrepare"), &m_strDriverProgId, wszName );
|
|
StdGetMetabaseProp ( pMB, MD_FS_PROPERTY_PATH, m_strDirectory, &m_strGroupPropFile, wszName );
|
|
StdGetMetabaseProp ( pMB, MD_EX_MDB_GUID, _T(""), &m_strMdbGuid, wszName );
|
|
|
|
//
|
|
// Get the win32 error code from RPC
|
|
//
|
|
DWORD dw = NntpGetVRootWin32Error( (LPWSTR)wszServerName, dwInstanceId, (LPWSTR)wszName, (LPDWORD)&m_dwWin32Error );
|
|
switch (dw) {
|
|
case ERROR_SERVICE_NOT_ACTIVE:
|
|
m_dwWin32Error = dw;
|
|
break;
|
|
|
|
case NOERROR:
|
|
break;
|
|
|
|
default:
|
|
hr = HRESULT_FROM_WIN32( dw );
|
|
goto Exit;
|
|
}
|
|
|
|
m_strNewsgroupSubtree = wszName;
|
|
m_fLogAccess = !dwDontLog;
|
|
|
|
if ( !m_strNewsgroupSubtree || !m_strDirectory || !m_strUNCUsername || !m_strUNCPassword ) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CVRoot::SendToMetabase ( CMetabaseKey * pMB, LPCWSTR wszName )
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
|
|
hr = pMB->SetString ( wszName, MD_KEY_TYPE, _T("IIsNntpVirtualDir"), METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pMB->SetString ( wszName, MD_VR_PATH, m_strDirectory, METADATA_INHERIT, IIS_MD_UT_FILE );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
StdPutMetabaseProp ( pMB, MD_ACCESS_PERM, m_bvAccess, wszName, IIS_MD_UT_FILE );
|
|
StdPutMetabaseProp ( pMB, MD_SSL_ACCESS_PERM, m_bvSslAccess, wszName, IIS_MD_UT_FILE );
|
|
StdPutMetabaseProp ( pMB, MD_DONT_LOG, !m_fLogAccess, wszName, IIS_MD_UT_FILE );
|
|
StdPutMetabaseProp ( pMB, MD_IS_CONTENT_INDEXED, m_fIndexContent, wszName, IIS_MD_UT_FILE );
|
|
StdPutMetabaseProp ( pMB, MD_WIN32_ERROR, m_dwWin32Error, wszName, IIS_MD_UT_SERVER, METADATA_VOLATILE );
|
|
StdPutMetabaseProp ( pMB, MD_VR_USERNAME, m_strUNCUsername, wszName, IIS_MD_UT_FILE );
|
|
StdPutMetabaseProp ( pMB, MD_VR_PASSWORD, m_strUNCPassword, wszName, IIS_MD_UT_FILE, METADATA_SECURE | METADATA_INHERIT );
|
|
StdPutMetabaseProp ( pMB, MD_VR_USE_ACCOUNT, m_dwUseAccount, wszName, IIS_MD_UT_SERVER );
|
|
StdPutMetabaseProp ( pMB, MD_VR_DO_EXPIRE, m_fDoExpire, wszName, IIS_MD_UT_SERVER );
|
|
StdPutMetabaseProp ( pMB, MD_VR_OWN_MODERATOR, m_fOwnModerator, wszName, IIS_MD_UT_SERVER );
|
|
StdPutMetabaseProp ( pMB, MD_VR_DRIVER_PROGID, m_strDriverProgId, wszName, IIS_MD_UT_SERVER );
|
|
StdPutMetabaseProp ( pMB, MD_FS_PROPERTY_PATH, m_strGroupPropFile, wszName, IIS_MD_UT_SERVER );
|
|
StdPutMetabaseProp ( pMB, MD_EX_MDB_GUID, m_strMdbGuid, wszName, IIS_MD_UT_SERVER );
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::InterfaceSupportsErrorInfo(REFIID riid)
|
|
{
|
|
static const IID* arr[] =
|
|
{
|
|
&IID_INntpVirtualRoot,
|
|
};
|
|
|
|
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
|
{
|
|
if (InlineIsEqualGUID(*arr[i],riid))
|
|
return S_OK;
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
CNntpVirtualRoot::CNntpVirtualRoot ()
|
|
// CComBSTR's are initialized to NULL by default.
|
|
{
|
|
}
|
|
|
|
CNntpVirtualRoot::~CNntpVirtualRoot ()
|
|
{
|
|
// All CComBSTR's are freed automatically.
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Properties:
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_NewsgroupSubtree ( BSTR * pstrNewsgroupSubtree )
|
|
{
|
|
return StdPropertyGet ( m_vroot.m_strNewsgroupSubtree, pstrNewsgroupSubtree );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_NewsgroupSubtree ( BSTR strNewsgroupSubtree )
|
|
{
|
|
if ( wcslen( strNewsgroupSubtree ) > METADATA_MAX_NAME_LEN - 20 ) return CO_E_PATHTOOLONG;
|
|
return StdPropertyPut ( &m_vroot.m_strNewsgroupSubtree, strNewsgroupSubtree );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_Directory ( BSTR * pstrDirectory )
|
|
{
|
|
return StdPropertyGet ( m_vroot.m_strDirectory, pstrDirectory );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_Directory ( BSTR strDirectory )
|
|
{
|
|
return StdPropertyPut ( &m_vroot.m_strDirectory, strDirectory );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_Win32Error ( long * plWin32Error )
|
|
{
|
|
return StdPropertyGet ( m_vroot.m_dwWin32Error, plWin32Error );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_LogAccess ( BOOL * pfLogAccess )
|
|
{
|
|
return StdPropertyGet ( m_vroot.m_fLogAccess, pfLogAccess );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_LogAccess ( BOOL fLogAccess )
|
|
{
|
|
return StdPropertyPut ( &m_vroot.m_fLogAccess, fLogAccess );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_IndexContent ( BOOL * pfIndexContent )
|
|
{
|
|
return StdPropertyGet ( m_vroot.m_fIndexContent, pfIndexContent );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_IndexContent ( BOOL fIndexContent )
|
|
{
|
|
return StdPropertyPut ( &m_vroot.m_fIndexContent, fIndexContent );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_AllowPosting ( BOOL * pfAllowPosting )
|
|
{
|
|
return StdPropertyGetBit ( m_vroot.m_bvAccess, MD_ACCESS_ALLOW_POSTING, pfAllowPosting );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_AllowPosting ( BOOL fAllowPosting )
|
|
{
|
|
return StdPropertyPutBit ( &m_vroot.m_bvAccess, MD_ACCESS_ALLOW_POSTING, fAllowPosting );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_RestrictGroupVisibility ( BOOL * pfRestrictGroupVisibility )
|
|
{
|
|
return StdPropertyGetBit ( m_vroot.m_bvAccess, MD_ACCESS_RESTRICT_VISIBILITY, pfRestrictGroupVisibility );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_RestrictGroupVisibility ( BOOL fRestrictGroupVisibility )
|
|
{
|
|
return StdPropertyPutBit ( &m_vroot.m_bvAccess, MD_ACCESS_RESTRICT_VISIBILITY, fRestrictGroupVisibility );
|
|
}
|
|
|
|
STDMETHODIMP SSLNegotiateCert ( BOOL * pfSSLNegotiateCert );
|
|
STDMETHODIMP SSLNegotiateCert ( BOOL fSSLNegotiateCert );
|
|
|
|
STDMETHODIMP SSLRequireCert ( BOOL * pfSSLRequireCert );
|
|
STDMETHODIMP SSLRequireCert ( BOOL fSSLRequireCert );
|
|
|
|
STDMETHODIMP SSLMapCert ( BOOL * pfSSLMapCert );
|
|
STDMETHODIMP SSLMapCert ( BOOL fSSLMapCert );
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_RequireSsl ( BOOL * pfRequireSsl )
|
|
{
|
|
return StdPropertyGetBit ( m_vroot.m_bvSslAccess, MD_ACCESS_SSL, pfRequireSsl );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_RequireSsl ( BOOL fRequireSsl )
|
|
{
|
|
return StdPropertyPutBit ( &m_vroot.m_bvSslAccess, MD_ACCESS_SSL, fRequireSsl );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_Require128BitSsl ( BOOL * pfRequire128BitSsl )
|
|
{
|
|
return StdPropertyGetBit ( m_vroot.m_bvSslAccess, MD_ACCESS_SSL128, pfRequire128BitSsl );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_Require128BitSsl ( BOOL fRequire128BitSsl )
|
|
{
|
|
return StdPropertyPutBit ( &m_vroot.m_bvSslAccess, MD_ACCESS_SSL128, fRequire128BitSsl );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_UNCUsername ( BSTR * pstrUNCUsername )
|
|
{
|
|
return StdPropertyGet ( m_vroot.m_strUNCUsername, pstrUNCUsername );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_UNCUsername ( BSTR strUNCUsername )
|
|
{
|
|
return StdPropertyPut ( &m_vroot.m_strUNCUsername, strUNCUsername );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_UNCPassword ( BSTR * pstrUNCPassword )
|
|
{
|
|
return StdPropertyGet ( m_vroot.m_strUNCPassword, pstrUNCPassword );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_UNCPassword ( BSTR strUNCPassword )
|
|
{
|
|
return StdPropertyPut ( &m_vroot.m_strUNCPassword, strUNCPassword );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_DriverProgId( BSTR *pstrDriverProgId )
|
|
{
|
|
return StdPropertyGet( m_vroot.m_strDriverProgId, pstrDriverProgId );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_DriverProgId( BSTR strDriverProgId )
|
|
{
|
|
return StdPropertyPut( &m_vroot.m_strDriverProgId, strDriverProgId );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_GroupPropFile( BSTR *pstrGroupPropFile )
|
|
{
|
|
return StdPropertyGet( m_vroot.m_strGroupPropFile, pstrGroupPropFile );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_GroupPropFile( BSTR strGroupPropFile )
|
|
{
|
|
return StdPropertyPut( &m_vroot.m_strGroupPropFile, strGroupPropFile );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_MdbGuid( BSTR *pstrMdbGuid )
|
|
{
|
|
return StdPropertyGet( m_vroot.m_strMdbGuid, pstrMdbGuid );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_MdbGuid( BSTR strMdbGuid )
|
|
{
|
|
return StdPropertyPut( &m_vroot.m_strMdbGuid, strMdbGuid );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_UseAccount( DWORD *pdwUseAccount )
|
|
{
|
|
return StdPropertyGet( m_vroot.m_dwUseAccount, pdwUseAccount );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_UseAccount( DWORD dwUseAccount )
|
|
{
|
|
return StdPropertyPut( &m_vroot.m_dwUseAccount, dwUseAccount );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_OwnExpire( BOOL *pfOwnExpire )
|
|
{
|
|
return StdPropertyGet( m_vroot.m_fDoExpire, pfOwnExpire );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_OwnExpire( BOOL fOwnExpire )
|
|
{
|
|
return StdPropertyPut( &m_vroot.m_fDoExpire, fOwnExpire );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::get_OwnModerator( BOOL *pfOwnModerator )
|
|
{
|
|
return StdPropertyGet( m_vroot.m_fOwnModerator, pfOwnModerator );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoot::put_OwnModerator( BOOL fOwnModerator )
|
|
{
|
|
return StdPropertyPut( &m_vroot.m_fOwnModerator, fOwnModerator );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::InterfaceSupportsErrorInfo(REFIID riid)
|
|
{
|
|
static const IID* arr[] =
|
|
{
|
|
&IID_INntpVirtualRoots,
|
|
};
|
|
|
|
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
|
{
|
|
if (InlineIsEqualGUID(*arr[i],riid))
|
|
return S_OK;
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
CNntpVirtualRoots::CNntpVirtualRoots () :
|
|
m_dwCount ( 0 ),
|
|
m_rgVRoots ( NULL ),
|
|
m_dwServiceInstance ( 0 )
|
|
// CComBSTR's are initialized to NULL by default.
|
|
{
|
|
}
|
|
|
|
CNntpVirtualRoots::~CNntpVirtualRoots ()
|
|
{
|
|
// All CComBSTR's are freed automatically.
|
|
|
|
delete [] m_rgVRoots;
|
|
}
|
|
|
|
HRESULT CNntpVirtualRoots::Init ( BSTR strServer, DWORD dwServiceInstance )
|
|
{
|
|
m_strServer = strServer;
|
|
m_dwServiceInstance = dwServiceInstance;
|
|
|
|
if ( !m_strServer ) {
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Properties:
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// Which service to configure:
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::get_Server ( BSTR * pstrServer )
|
|
{
|
|
return StdPropertyGet ( m_strServer, pstrServer );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::put_Server ( BSTR strServer )
|
|
{
|
|
_ASSERT ( strServer );
|
|
_ASSERT ( IS_VALID_STRING ( strServer ) );
|
|
|
|
if ( strServer == NULL ) {
|
|
return E_POINTER;
|
|
}
|
|
|
|
if ( lstrcmp ( strServer, _T("") ) == 0 ) {
|
|
m_strServer.Empty();
|
|
|
|
return NOERROR;
|
|
}
|
|
else {
|
|
return StdPropertyPutServerName ( &m_strServer, strServer );
|
|
}
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::get_ServiceInstance ( long * plServiceInstance )
|
|
{
|
|
return StdPropertyGet ( m_dwServiceInstance, plServiceInstance );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::put_ServiceInstance ( long lServiceInstance )
|
|
{
|
|
return StdPropertyPut ( &m_dwServiceInstance, lServiceInstance );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::get_Count ( long * pdwCount )
|
|
{
|
|
return StdPropertyGet ( m_dwCount, pdwCount );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Methods:
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::Enumerate ( )
|
|
{
|
|
TraceFunctEnter ( "CNntpVirtualRoots::Enumerate" );
|
|
|
|
HRESULT hr = NOERROR;
|
|
CComPtr<IMSAdminBase> pMetabase;
|
|
|
|
// Clear the old enumeration:
|
|
delete [] m_rgVRoots;
|
|
m_rgVRoots = NULL;
|
|
m_dwCount = 0;
|
|
|
|
hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
hr = GetVRootsFromMetabase ( pMetabase );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
TRACE_HRESULT(hr);
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::Item (
|
|
long index,
|
|
INntpVirtualRoot ** ppVirtualRoot
|
|
)
|
|
{
|
|
TraceFunctEnter ( "CNntpVirtualRoots::Item" );
|
|
|
|
_ASSERT ( IS_VALID_OUT_PARAM ( ppVirtualRoot ) );
|
|
|
|
*ppVirtualRoot = NULL;
|
|
|
|
HRESULT hr = NOERROR;
|
|
CComObject<CNntpVirtualRoot> * pVirtualRoot = NULL;
|
|
|
|
if ( index < 0 || index >= m_dwCount ) {
|
|
hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
|
|
goto Exit;
|
|
}
|
|
|
|
hr = CComObject<CNntpVirtualRoot>::CreateInstance ( &pVirtualRoot );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
_ASSERT ( pVirtualRoot );
|
|
hr = pVirtualRoot->SetProperties ( m_rgVRoots[index] );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
hr = pVirtualRoot->QueryInterface ( IID_INntpVirtualRoot, (void **) ppVirtualRoot );
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
|
|
Exit:
|
|
if ( FAILED(hr) ) {
|
|
delete pVirtualRoot;
|
|
}
|
|
|
|
TRACE_HRESULT(hr);
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::Add (
|
|
INntpVirtualRoot * pVirtualRoot
|
|
)
|
|
{
|
|
TraceFunctEnter ( "CNntpVirtualRoots::Add" );
|
|
|
|
_ASSERT ( IS_VALID_IN_PARAM ( pVirtualRoot ) );
|
|
|
|
HRESULT hr = NOERROR;
|
|
CVRoot * rgNewVirtualRoots = NULL;
|
|
long i;
|
|
CComPtr<IMSAdminBase> pMetabase;
|
|
CVRoot newVroot;
|
|
WCHAR wszName [ 2*METADATA_MAX_NAME_LEN ];
|
|
WCHAR wszVRootPath [ 2*METADATA_MAX_NAME_LEN ];
|
|
|
|
// Validate the new Virtual Root:
|
|
hr = newVroot.SetProperties ( pVirtualRoot );
|
|
if ( FAILED(hr) ) {
|
|
return hr;
|
|
}
|
|
|
|
if ( !newVroot.m_strNewsgroupSubtree ||
|
|
!newVroot.m_strNewsgroupSubtree[0] ) {
|
|
|
|
return RETURNCODETOHRESULT ( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
// Add the new virtual root to the metabase:
|
|
GetVRootName ( newVroot.m_strNewsgroupSubtree, wszName );
|
|
|
|
//
|
|
// The sub tree itself should not exceed length METADATA_MAX_NAME_LEN
|
|
//
|
|
_ASSERT( wcslen( wszName ) <= METADATA_MAX_NAME_LEN );
|
|
if ( wcslen( wszName ) > METADATA_MAX_NAME_LEN ) {
|
|
return CO_E_PATHTOOLONG;
|
|
}
|
|
|
|
hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
|
|
if ( FAILED(hr) ) {
|
|
return hr;
|
|
}
|
|
|
|
CMetabaseKey mb ( pMetabase );
|
|
|
|
GetMDVRootPath ( wszVRootPath );
|
|
|
|
//
|
|
// I trust wszVRootPath, it's shorter than METADATA_MAX_NAME_LEN
|
|
//
|
|
|
|
//
|
|
// Test to see if this item exists already:
|
|
//
|
|
|
|
WCHAR wszTempPath [ 2 * METADATA_MAX_NAME_LEN + 1];
|
|
|
|
wsprintf ( wszTempPath, _T("%s%s"), wszVRootPath, wszName );
|
|
if ( wcslen( wszTempPath ) > METADATA_MAX_NAME_LEN ) {
|
|
|
|
//
|
|
// I can't handle it either
|
|
//
|
|
return CO_E_PATHTOOLONG;
|
|
}
|
|
|
|
hr = mb.Open ( wszTempPath );
|
|
if ( SUCCEEDED(hr) ) {
|
|
DWORD cbVrootDir;
|
|
|
|
if ( SUCCEEDED ( mb.GetDataSize (
|
|
_T(""),
|
|
MD_VR_PATH,
|
|
STRING_METADATA,
|
|
&cbVrootDir,
|
|
METADATA_NO_ATTRIBUTES )
|
|
) ) {
|
|
|
|
mb.Close();
|
|
|
|
hr = NntpCreateException ( IDS_NNTPEXCEPTION_VROOT_ALREADY_EXISTS );
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
hr = mb.Open ( wszVRootPath, METADATA_PERMISSION_WRITE );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
/*
|
|
hr = mb.CreateChild ( wszName );
|
|
BAIL_ON_FAILURE(hr);
|
|
*/
|
|
|
|
hr = newVroot.SendToMetabase ( &mb, wszName );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = mb.Save ();
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
// Allocate the new VirtualRoot array:
|
|
rgNewVirtualRoots = new CVRoot [ m_dwCount + 1 ];
|
|
if ( !rgNewVirtualRoots ) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
// Copy the old VirtualRoots to the new array:
|
|
for ( i = 0; i < m_dwCount; i++ ) {
|
|
hr = rgNewVirtualRoots[i].SetProperties ( m_rgVRoots[i] );
|
|
if ( FAILED (hr) ) {
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Add the new VirtualRoot to the end of the array:
|
|
hr = rgNewVirtualRoots[m_dwCount].SetProperties ( pVirtualRoot );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
delete [] m_rgVRoots;
|
|
m_rgVRoots = rgNewVirtualRoots;
|
|
m_dwCount++;
|
|
|
|
Exit:
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::Set (
|
|
long index,
|
|
INntpVirtualRoot * pVirtualRoot
|
|
)
|
|
{
|
|
TraceFunctEnter ( "CNntpVirtualRoots::ChangeVirtualRoot" );
|
|
|
|
HRESULT hr = NOERROR;
|
|
|
|
CComBSTR strNewsgroupSubtree;
|
|
CComBSTR strDirectory;
|
|
CVRoot temp;
|
|
CComPtr<IMSAdminBase> pMetabase;
|
|
WCHAR wszVRootPath [ METADATA_MAX_NAME_LEN ];
|
|
WCHAR wszName [ METADATA_MAX_NAME_LEN ];
|
|
|
|
// Send the new virtual root to the metabase:
|
|
hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
|
|
if ( FAILED(hr) ) {
|
|
return hr;
|
|
}
|
|
|
|
CMetabaseKey mb ( pMetabase );
|
|
|
|
if ( index < 0 || index >= m_dwCount ) {
|
|
hr = NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
|
|
goto Exit;
|
|
}
|
|
|
|
hr = temp.SetProperties ( pVirtualRoot );
|
|
if ( FAILED(hr) ) {
|
|
goto Exit;
|
|
}
|
|
|
|
GetMDVRootPath ( wszVRootPath );
|
|
|
|
hr = mb.Open ( wszVRootPath, METADATA_PERMISSION_WRITE );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
GetVRootName ( temp.m_strNewsgroupSubtree, wszName );
|
|
|
|
hr = temp.SendToMetabase ( &mb, wszName );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = m_rgVRoots[index].SetProperties ( pVirtualRoot );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
Exit:
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::Remove ( long index )
|
|
{
|
|
TraceFunctEnter ( "CNntpVirtualRoots::Remove" );
|
|
|
|
HRESULT hr = NOERROR;
|
|
CVRoot temp;
|
|
long cPositionsToSlide;
|
|
CComPtr<IMSAdminBase> pMetabase;
|
|
WCHAR wszName [ METADATA_MAX_NAME_LEN ];
|
|
WCHAR wszVRootPath [ METADATA_MAX_NAME_LEN ];
|
|
|
|
if ( index < 0 || index >= m_dwCount ) {
|
|
return NntpCreateException ( IDS_NNTPEXCEPTION_INVALID_INDEX );
|
|
}
|
|
|
|
// Delete the virtual root from the metabase:
|
|
|
|
hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pMetabase );
|
|
if ( FAILED(hr) ) {
|
|
return hr;
|
|
}
|
|
|
|
CMetabaseKey mb ( pMetabase );
|
|
|
|
GetMDVRootPath ( wszVRootPath );
|
|
|
|
hr = mb.Open ( wszVRootPath, METADATA_PERMISSION_WRITE );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
GetVRootName ( m_rgVRoots[index].m_strNewsgroupSubtree, wszName );
|
|
|
|
hr = mb.DeleteAllData ( wszName );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
/*
|
|
hr = mb.DestroyChild ( wszName );
|
|
BAIL_ON_FAILURE(hr);
|
|
*/
|
|
|
|
hr = mb.Save ();
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
mb.Close ();
|
|
|
|
// Slide the array down by one position:
|
|
|
|
_ASSERT ( m_rgVRoots );
|
|
|
|
cPositionsToSlide = (m_dwCount - 1) - index;
|
|
|
|
_ASSERT ( cPositionsToSlide < m_dwCount );
|
|
|
|
if ( cPositionsToSlide > 0 ) {
|
|
// Save the deleted VirtualRoot in temp:
|
|
CopyMemory ( &temp, &m_rgVRoots[index], sizeof ( CVRoot ) );
|
|
|
|
// Move the array down one:
|
|
MoveMemory ( &m_rgVRoots[index], &m_rgVRoots[index + 1], sizeof ( CVRoot ) * cPositionsToSlide );
|
|
|
|
// Put the deleted VirtualRoot on the end (so it gets destructed):
|
|
CopyMemory ( &m_rgVRoots[m_dwCount - 1], &temp, sizeof ( CVRoot ) );
|
|
|
|
// Zero out the temp VirtualRoot:
|
|
ZeroMemory ( &temp, sizeof ( CVRoot ) );
|
|
}
|
|
|
|
m_dwCount--;
|
|
|
|
Exit:
|
|
TraceFunctLeave ();
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::Find ( BSTR strNewsgroupSubtree, long * pIndex )
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
long i;
|
|
|
|
_ASSERT ( pIndex );
|
|
*pIndex = -1;
|
|
|
|
for ( i = 0; i < m_dwCount; i++ ) {
|
|
|
|
if ( lstrcmp ( m_rgVRoots[i].m_strNewsgroupSubtree, strNewsgroupSubtree ) == 0 ) {
|
|
*pIndex = i;
|
|
}
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
static HRESULT CountVrootsIterator (
|
|
CMetabaseKey * pMB,
|
|
LPCWSTR wszVrootPath,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
DWORD * pcVroots = (DWORD *) lParam;
|
|
|
|
(*pcVroots)++;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
typedef struct tagAddVrootsParms
|
|
{
|
|
DWORD cCount;
|
|
CVRoot * rgVroots;
|
|
DWORD dwCurrentIndex;
|
|
LPWSTR wszServerName;
|
|
DWORD dwInstanceId;
|
|
} ADD_VROOTS_PARMS;
|
|
|
|
static HRESULT AddVrootsIterator (
|
|
CMetabaseKey * pMB,
|
|
LPCWSTR wszVrootPath,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
_ASSERT ( pMB );
|
|
_ASSERT ( wszVrootPath );
|
|
_ASSERT ( lParam );
|
|
|
|
HRESULT hr;
|
|
ADD_VROOTS_PARMS * pParms = (ADD_VROOTS_PARMS *) lParam;
|
|
LPWSTR wszServerName = pParms->wszServerName;
|
|
DWORD dwInstanceId = pParms->dwInstanceId;
|
|
|
|
_ASSERT ( pParms->dwCurrentIndex < pParms->cCount );
|
|
|
|
hr = pParms->rgVroots[pParms->dwCurrentIndex].GetFromMetabase (
|
|
pMB,
|
|
wszVrootPath,
|
|
dwInstanceId,
|
|
wszServerName
|
|
);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
pParms->dwCurrentIndex++;
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CNntpVirtualRoots::GetVRootsFromMetabase ( IMSAdminBase * pMetabase )
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
CMetabaseKey mb ( pMetabase );
|
|
WCHAR wszVRootPath [ METADATA_MAX_NAME_LEN ];
|
|
DWORD cCount = 0;
|
|
CVRoot * rgVroots = NULL;
|
|
ADD_VROOTS_PARMS parms;
|
|
|
|
//
|
|
// Initialize the metabase:
|
|
//
|
|
|
|
GetMDVRootPath ( wszVRootPath );
|
|
|
|
hr = mb.Open ( wszVRootPath );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// Count the virtual roots:
|
|
//
|
|
|
|
hr = IterateOverVroots ( &mb, CountVrootsIterator, (LPARAM) &cCount );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// Create the virtual roots array:
|
|
//
|
|
|
|
rgVroots = new CVRoot [ cCount ];
|
|
if ( !rgVroots ) {
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Add the virtual roots to the array:
|
|
//
|
|
|
|
parms.cCount = cCount;
|
|
parms.rgVroots = rgVroots;
|
|
parms.dwCurrentIndex = 0;
|
|
parms.wszServerName = m_strServer;
|
|
parms.dwInstanceId = m_dwServiceInstance;
|
|
|
|
hr = IterateOverVroots ( &mb, AddVrootsIterator, (LPARAM) &parms );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
_ASSERT ( SUCCEEDED(hr) );
|
|
_ASSERT ( m_rgVRoots == NULL );
|
|
m_rgVRoots = rgVroots;
|
|
m_dwCount = cCount;
|
|
|
|
Exit:
|
|
if ( FAILED(hr) ) {
|
|
delete [] rgVroots;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CNntpVirtualRoots::IterateOverVroots (
|
|
CMetabaseKey * pMB,
|
|
VROOT_ITERATOR fpIterator,
|
|
LPARAM lParam,
|
|
LPCWSTR wszPath // = _T("")
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
WCHAR wszSubKey[ METADATA_MAX_NAME_LEN ];
|
|
WCHAR wszSubPath[ METADATA_MAX_NAME_LEN ];
|
|
BOOL fRealVroot;
|
|
DWORD cbVrootDir;
|
|
DWORD i;
|
|
|
|
//
|
|
// Is this a real vroot?
|
|
//
|
|
|
|
fRealVroot =
|
|
!*wszPath || // Always count the home directory
|
|
SUCCEEDED ( pMB->GetDataSize (
|
|
wszPath,
|
|
MD_VR_PATH,
|
|
STRING_METADATA,
|
|
&cbVrootDir,
|
|
METADATA_NO_ATTRIBUTES )
|
|
);
|
|
|
|
if ( fRealVroot ) {
|
|
// Call the iterator on this key:
|
|
|
|
hr = (*fpIterator) ( pMB, wszPath, lParam );
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
//
|
|
// Recurse down the tree:
|
|
//
|
|
|
|
for ( i = 0; ; ) {
|
|
hr = pMB->EnumObjects ( wszPath, wszSubKey, i );
|
|
|
|
if ( HRESULTTOWIN32(hr) == ERROR_NO_MORE_ITEMS ) {
|
|
// This is expected, end the loop:
|
|
|
|
if ( !fRealVroot && i == 0 ) {
|
|
//
|
|
// This key isn't a vroot and has no children, so delete it.
|
|
//
|
|
|
|
hr = pMB->ChangePermissions ( METADATA_PERMISSION_WRITE );
|
|
if ( SUCCEEDED(hr) ) {
|
|
hr = pMB->DeleteKey ( wszPath );
|
|
}
|
|
|
|
pMB->ChangePermissions ( METADATA_PERMISSION_READ );
|
|
if ( SUCCEEDED(hr) ) {
|
|
hr = pMB->Save ();
|
|
}
|
|
|
|
if ( SUCCEEDED(hr) ) {
|
|
//
|
|
// Tell our parent that this key was deleted.
|
|
//
|
|
|
|
hr = S_FALSE;
|
|
}
|
|
else {
|
|
//
|
|
// Ignore any deleting problems:
|
|
//
|
|
|
|
hr = NOERROR;
|
|
}
|
|
}
|
|
else {
|
|
hr = NOERROR;
|
|
}
|
|
break;
|
|
}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if ( *wszPath ) {
|
|
if ( _snwprintf ( wszSubPath, sizeof(wszSubKey)/sizeof(wszSubKey[0]) - 1, _T("%s/%s"), wszPath, wszSubKey ) < 0 )
|
|
{
|
|
// Theoretically impossible because of the name length restriction of metabase
|
|
// If it really happens, skip the recursive call and go on to the next one
|
|
hr = NOERROR;
|
|
i++;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
wszSubPath[sizeof(wszSubKey)/sizeof(wszSubKey[0]) - 1] = L'\0';
|
|
}
|
|
}
|
|
else {
|
|
wcscpy ( wszSubPath, wszSubKey );
|
|
}
|
|
|
|
hr = IterateOverVroots ( pMB, fpIterator, lParam, wszSubPath );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
if ( hr != S_FALSE ) {
|
|
//
|
|
// This means the child key still exists, so increment
|
|
// the counter and go on to the next one.
|
|
//
|
|
|
|
i++;
|
|
}
|
|
//
|
|
// Else the return code is S_FALSE, which means the current key
|
|
// has been deleted, shifting all indicies down by one. Therefore,
|
|
// there is no need to increment i.
|
|
//
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
void CNntpVirtualRoots::GetVRootName ( LPWSTR wszDisplayName, LPWSTR wszPathName )
|
|
{
|
|
wcscpy ( wszPathName, wszDisplayName );
|
|
}
|
|
|
|
void CNntpVirtualRoots::GetMDVRootPath ( LPWSTR wszPath )
|
|
{
|
|
GetMDInstancePath ( wszPath, m_dwServiceInstance );
|
|
|
|
wcscat ( wszPath, _T("Root/") );
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::ItemDispatch ( long index, IDispatch ** ppDispatch )
|
|
{
|
|
HRESULT hr;
|
|
CComPtr<INntpVirtualRoot> pVirtualRoot;
|
|
|
|
hr = Item ( index, &pVirtualRoot );
|
|
BAIL_ON_FAILURE ( hr );
|
|
|
|
hr = pVirtualRoot->QueryInterface ( IID_IDispatch, (void **) ppDispatch );
|
|
BAIL_ON_FAILURE ( hr );
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::AddDispatch ( IDispatch * pVirtualRoot )
|
|
{
|
|
HRESULT hr;
|
|
CComPtr<INntpVirtualRoot> pINntpVirtualRoot;
|
|
|
|
hr = pVirtualRoot->QueryInterface ( IID_INntpVirtualRoot, (void **) &pINntpVirtualRoot );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = Add ( pINntpVirtualRoot );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CNntpVirtualRoots::SetDispatch ( long lIndex, IDispatch * pVirtualRoot )
|
|
{
|
|
HRESULT hr;
|
|
CComPtr<INntpVirtualRoot> pINntpVirtualRoot;
|
|
|
|
hr = pVirtualRoot->QueryInterface ( IID_INntpVirtualRoot, (void **) &pINntpVirtualRoot );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = Set ( lIndex, pINntpVirtualRoot );
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|