Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2668 lines
76 KiB

// server.cpp : Implementation of CnntpadmApp and DLL registration.
#include "stdafx.h"
#include <lmcons.h>
#include <sddl.h>
#include "nntpcmn.h"
#include "oleutil.h"
#include "cmultisz.h"
#include "metautil.h"
#include "metakey.h"
#include "server.h"
// Must define THIS_FILE_* macros to use NntpCreateException()
#define THIS_FILE_HELP_CONTEXT 0
#define THIS_FILE_PROG_ID _T("Nntpadm.VirtualServer.1")
#define THIS_FILE_IID IID_INntpVirtualServer
// Bitmasks for changed fields:
#define CHNG_ARTICLETIMELIMIT 0x00000001
#define CHNG_HISTORYEXPIRATION 0x00000002
#define CHNG_HONORCLIENTMSGIDS 0x00000004
#define CHNG_SMTPSERVER 0x00000008
#define CHNG_ALLOWCLIENTPOSTS 0x00000010
#define CHNG_ALLOWFEEDPOSTS 0x00000020
#define CHNG_ALLOWCONTROLMSGS 0x00000040
#define CHNG_DEFAULTMODERATORDOMAIN 0x00000080
#define CHNG_COMMANDLOGMASK 0x00000100
#define CHNG_DISABLENEWNEWS 0x00000200
#define CHNG_NEWSCRAWLERTIME 0x00000400
#define CHNG_SHUTDOWNLATENCY 0x00000800
#define CHNG_CLIENTPOSTHARDLIMIT 0x00001000
#define CHNG_CLIENTPOSTSOFTLIMIT 0x00002000
#define CHNG_FEEDPOSTHARDLIMIT 0x00004000
#define CHNG_FEEDPOSTSOFTLIMIT 0x00008000
#define CHNG_GROUPHELPFILE 0x00010000
#define CHNG_GROUPLISTFILE 0x00020000
#define CHNG_ARTICLETABLEFILE 0x00040000
#define CHNG_HISTORYTABLEFILE 0x00080000
#define CHNG_MODERATORFILE 0x00100000
#define CHNG_XOVERTABLEFILE 0x00200000
#define CHNG_DISPLAYNAME 0x00400000
#define CHNG_ERRORCONTROL 0x00800000
#define CHNG_CLEANBOOT 0x01000000
#define CHNG_UUCPNAME 0x02000000
#define CHNG_ORGANIZATION 0x04000000
#define CHNG_AUTOSTART 0x08000000
#define CHNG_COMMENT 0x10000000
#define CHNG_BINDING 0x20000000
#define CHNG_SECUREPORT 0x40000000
#define CHNG_MAXCONNECTIONS 0x80000000
#define CHNG2_CONNECTIONTIMEOUT 0x00000001
#define CHNG2_ANONYMOUSUSERNAME 0x00000002
#define CHNG2_ANONYMOUSUSERPASS 0x00000004
#define CHNG2_PICKUPDIRECTORY 0x00000008
#define CHNG2_FAILEDPICKUPDIRECTORY 0x00000010
#define CHNG2_HOMEDIRECTORY 0x00000020
#define CHNG2_NTAUTHENTICATION_PROVIDERS 0x00000040
#define CHNG2_AUTHORIZATION 0x00000080
#define CHNG2_ENABLELOGGING 0x00000100
#define CHNG2_SSLACCESS 0x00000200
#define CHNG2_AUTOSYNCPASSWORD 0x00000400
#define CHNG2_ADMINEMAIL 0x00000800
#define CHNG2_CLUSTERENABLED 0x00001000
#define CHNG2_ADMINACL 0x00002000
#define NNTP_DEF_ADMIN_EMAIL _T( "" )
#define NNTP_DEF_NTAUTHENTICATION_PROVIDERS _T("NTLM\0")
#define NNTP_DEF_AUTHORIZATION ( 0 )
#define NNTP_DEF_ENABLE_LOGGING ( FALSE )
#define NNTP_DEF_SECURE_BINDINGS ( _T("\0") )
// Parameter ranges:
#define MAXLEN_SERVER ( 256 )
#define MIN_ARTICLETIMELIMIT ( (DWORD) 0 )
#define MAX_ARTICLETIMELIMIT ( (DWORD) -1 )
#define MIN_HISTORYEXPIRATION ( (DWORD) 0 )
#define MAX_HISTORYEXPIRATION ( (DWORD) -1 )
#define MAXLEN_SMTPSERVER ( 256 )
#define MAXLEN_DEFAULTMODERATORDOMAIN ( 256 )
#define MIN_COMMANDLOGMASK ( (DWORD) 0 )
#define MAX_COMMANDLOGMASK ( (DWORD) -1 )
#define MIN_NEWSCRAWLERTIME ( (DWORD) 1 )
#define MAX_NEWSCRAWLERTIME ( (DWORD) -1 )
#define MIN_SHUTDOWNLATENCY ( (DWORD) 1 )
#define MAX_SHUTDOWNLATENCY ( (DWORD) -1 )
//
// Administrator ACL:
//
static HRESULT AclToAdministrators ( LPCTSTR strServer, PSECURITY_DESCRIPTOR pSDRelative, SAFEARRAY ** ppsaAdmins );
static HRESULT AdministratorsToAcl ( LPCTSTR strServer, SAFEARRAY * psaAdmins, PSECURITY_DESCRIPTOR* ppSD, DWORD * pcbSD );
static HRESULT SidToString ( LPCWSTR strSystemName, PSID pSID, BSTR * pStr );
static HRESULT StringToSid ( LPCWSTR strSystemName, LPWSTR str, PSID * ppSID );
/////////////////////////////////////////////////////////////////////////////
//
CNntpVirtualServer::CNntpVirtualServer () :
m_dwServiceInstance ( 0 ),
m_dwClientPostHardLimit ( 0 ),
m_dwClientPostSoftLimit ( 0 ),
m_dwFeedPostHardLimit ( 0 ),
m_dwFeedPostSoftLimit ( 0 ),
m_dwEncryptionCapabilities ( 0 ),
m_fAutoSyncPassword ( FALSE ),
m_fErrorControl ( FALSE ),
m_fCleanBoot ( FALSE ),
m_fAutoStart ( FALSE ),
m_psaAdmins ( NULL ),
m_State ( NNTP_SERVER_STATE_UNKNOWN ),
m_dwWin32ErrorCode ( NOERROR ),
m_pPrivateBindings ( NULL ),
m_pPrivateIpAccess ( NULL ),
// m_pPrivateHomeDirectory ( NULL ),
m_fGotProperties ( FALSE ),
m_fClusterEnabled ( FALSE ),
m_bvChangedFields ( 0 ),
m_bvChangedFields2 ( 0 )
// CComBSTR's are initialized to NULL by default.
{
InitAsyncTrace ( );
// Create the Ip Access collection:
CComObject<CTcpAccess> * pIpAccess;
CComObject<CTcpAccess>::CreateInstance ( &pIpAccess );
pIpAccess->QueryInterface ( IID_ITcpAccess, (void **) &m_pIpAccess );
m_pPrivateIpAccess = pIpAccess;
}
CNntpVirtualServer::~CNntpVirtualServer ()
{
// All CComBSTR's are freed automatically.
if ( m_psaAdmins ) {
SafeArrayDestroy ( m_psaAdmins );
}
TermAsyncTrace ( );
}
STDMETHODIMP CNntpVirtualServer::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_INntpVirtualServer,
};
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}
// Which service to configure:
STDMETHODIMP CNntpVirtualServer::get_Server ( BSTR * pstrServer )
{
return StdPropertyGet ( m_strServer, pstrServer );
}
STDMETHODIMP CNntpVirtualServer::put_Server ( BSTR strServer )
{
VALIDATE_STRING ( strServer, MAXLEN_SERVER );
// If the server name changes, that means the client will have to
// call Get again:
// I assume this here:
_ASSERT ( sizeof (DWORD) == sizeof (int) );
return StdPropertyPutServerName ( &m_strServer, strServer, (DWORD *) &m_fGotProperties, 1 );
}
STDMETHODIMP CNntpVirtualServer::get_ServiceInstance ( long * plServiceInstance )
{
return StdPropertyGet ( m_dwServiceInstance, plServiceInstance );
}
STDMETHODIMP CNntpVirtualServer::put_ServiceInstance ( long lServiceInstance )
{
// If the service instance changes, that means the client will have to
// call Get again:
// I assume this here:
_ASSERT ( sizeof (DWORD) == sizeof (int) );
return StdPropertyPut ( &m_dwServiceInstance, lServiceInstance, (DWORD *) &m_fGotProperties, 1 );
}
// Other admin interfaces for virtual servers:
STDMETHODIMP CNntpVirtualServer::get_FeedsAdmin ( IDispatch ** ppIDispatch )
{
HRESULT hr = NOERROR;
CComPtr<INntpAdminFeeds> pINntpAdminFeeds;
CComBSTR strTemp = _T("");
if (!strTemp)
{
hr = E_OUTOFMEMORY;
goto Error;
}
hr = StdPropertyHandoffIDispatch (
CLSID_CNntpAdminFeeds,
IID_INntpAdminFeeds,
&pINntpAdminFeeds,
ppIDispatch
);
if ( FAILED(hr) ) {
goto Error;
}
// Set default properties:
hr = pINntpAdminFeeds->put_Server ( m_strServer ? m_strServer : strTemp );
if ( FAILED (hr) ) {
goto Error;
}
hr = pINntpAdminFeeds->put_ServiceInstance ( m_dwServiceInstance );
if ( FAILED (hr) ) {
goto Error;
}
return hr;
Error:
SAFE_RELEASE ( *ppIDispatch );
*ppIDispatch = NULL;
return hr;
// Destructor releases pINntpAdminFeeds
}
STDMETHODIMP CNntpVirtualServer::get_GroupsAdmin ( IDispatch ** ppIDispatch )
{
HRESULT hr = NOERROR;
CComPtr<INntpAdminGroups> pINntpAdminGroups;
CComBSTR strTemp = _T("");
if (!strTemp)
{
hr = E_OUTOFMEMORY;
goto Error;
}
hr = StdPropertyHandoffIDispatch (
CLSID_CNntpAdminGroups,
IID_INntpAdminGroups,
&pINntpAdminGroups,
ppIDispatch
);
if ( FAILED(hr) ) {
goto Error;
}
// Set default properties:
hr = pINntpAdminGroups->put_Server ( m_strServer ? m_strServer : strTemp );
if ( FAILED (hr) ) {
goto Error;
}
hr = pINntpAdminGroups->put_ServiceInstance ( m_dwServiceInstance );
if ( FAILED (hr) ) {
goto Error;
}
return hr;
Error:
SAFE_RELEASE ( *ppIDispatch );
*ppIDispatch = NULL;
return hr;
// Destructor releases pINntpAdminGroups
}
STDMETHODIMP CNntpVirtualServer::get_ExpirationAdmin ( IDispatch ** ppIDispatch )
{
HRESULT hr = NOERROR;
CComPtr<INntpAdminExpiration> pINntpAdminExpiration;
CComBSTR strTemp = _T("");
if (!strTemp)
{
hr = E_OUTOFMEMORY;
goto Error;
}
hr = StdPropertyHandoffIDispatch (
CLSID_CNntpAdminExpiration,
IID_INntpAdminExpiration,
&pINntpAdminExpiration,
ppIDispatch
);
if ( FAILED(hr) ) {
goto Error;
}
// Set default properties:
hr = pINntpAdminExpiration->put_Server ( m_strServer ? m_strServer : strTemp );
if ( FAILED (hr) ) {
goto Error;
}
hr = pINntpAdminExpiration->put_ServiceInstance ( m_dwServiceInstance );
if ( FAILED (hr) ) {
goto Error;
}
return hr;
Error:
SAFE_RELEASE ( *ppIDispatch );
*ppIDispatch = NULL;
return hr;
// Destructor releases pINntpAdminExpiration
}
STDMETHODIMP CNntpVirtualServer::get_SessionsAdmin ( IDispatch ** ppIDispatch )
{
HRESULT hr = NOERROR;
CComPtr<INntpAdminSessions> pINntpAdminSessions;
CComBSTR strTemp = _T("");
if (!strTemp)
{
hr = E_OUTOFMEMORY;
goto Error;
}
hr = StdPropertyHandoffIDispatch (
CLSID_CNntpAdminSessions,
IID_INntpAdminSessions,
&pINntpAdminSessions,
ppIDispatch
);
if ( FAILED(hr) ) {
goto Error;
}
// Set default properties:
hr = pINntpAdminSessions->put_Server ( m_strServer ? m_strServer : strTemp );
if ( FAILED (hr) ) {
goto Error;
}
hr = pINntpAdminSessions->put_ServiceInstance ( m_dwServiceInstance );
if ( FAILED (hr) ) {
goto Error;
}
return hr;
Error:
SAFE_RELEASE ( *ppIDispatch );
*ppIDispatch = NULL;
return hr;
// Destructor releases pINntpAdminSessions
}
STDMETHODIMP CNntpVirtualServer::get_RebuildAdmin ( IDispatch ** ppIDispatch )
{
HRESULT hr = NOERROR;
CComPtr<INntpAdminRebuild> pINntpAdminRebuild;
CComBSTR strTemp = _T("");
if (!strTemp)
{
hr = E_OUTOFMEMORY;
goto Error;
}
hr = StdPropertyHandoffIDispatch (
CLSID_CNntpAdminRebuild,
IID_INntpAdminRebuild,
&pINntpAdminRebuild,
ppIDispatch
);
if ( FAILED(hr) ) {
goto Error;
}
// Set default properties:
hr = pINntpAdminRebuild->put_Server ( m_strServer ? m_strServer : strTemp );
if ( FAILED (hr) ) {
goto Error;
}
hr = pINntpAdminRebuild->put_ServiceInstance ( m_dwServiceInstance );
if ( FAILED (hr) ) {
goto Error;
}
return hr;
Error:
SAFE_RELEASE ( *ppIDispatch );
*ppIDispatch = NULL;
return hr;
// Destructor releases pINntpAdminRebuild
}
STDMETHODIMP CNntpVirtualServer::get_VirtualRoots ( INntpVirtualRoots ** ppVirtualRoots )
{
HRESULT hr = NOERROR;
CComObject<CNntpVirtualRoots> * pVRoots = NULL;
*ppVirtualRoots = NULL;
hr = CComObject<CNntpVirtualRoots>::CreateInstance ( &pVRoots );
if ( FAILED(hr) ) {
goto Error;
}
// Set default properties:
pVRoots->m_strServer = m_strServer;
pVRoots->m_dwServiceInstance = m_dwServiceInstance;
if ( m_strServer && !pVRoots->m_strServer ) {
hr = E_OUTOFMEMORY;
goto Error;
}
hr = pVRoots->QueryInterface ( IID_INntpVirtualRoots, (void **) ppVirtualRoots );
Error:
if ( FAILED(hr) ) {
delete pVRoots;
}
return hr;
// Destructor releases pINntpAdminRebuild
}
STDMETHODIMP CNntpVirtualServer::get_VirtualRootsDispatch ( IDispatch ** ppVirtualRoots )
{
HRESULT hr;
CComPtr<INntpVirtualRoots> pVRoots;
hr = get_VirtualRoots ( &pVRoots );
BAIL_ON_FAILURE ( hr );
hr = pVRoots->QueryInterface ( IID_IDispatch, (void **) ppVirtualRoots );
BAIL_ON_FAILURE ( hr );
Exit:
return hr;
}
STDMETHODIMP CNntpVirtualServer::get_TcpAccess ( ITcpAccess ** ppTcpAccess )
{
return m_pIpAccess->QueryInterface ( IID_ITcpAccess, (void **) ppTcpAccess );
}
// Server overridable Properties:
STDMETHODIMP CNntpVirtualServer::get_ArticleTimeLimit ( long * plArticleTimeLimit )
{
return StdPropertyGet ( m_dwArticleTimeLimit, plArticleTimeLimit );
}
STDMETHODIMP CNntpVirtualServer::put_ArticleTimeLimit ( long lArticleTimeLimit )
{
return StdPropertyPut ( &m_dwArticleTimeLimit, lArticleTimeLimit, &m_bvChangedFields, CHNG_ARTICLETIMELIMIT );
}
STDMETHODIMP CNntpVirtualServer::get_HistoryExpiration ( long * plHistoryExpiration )
{
return StdPropertyGet ( m_dwHistoryExpiration, plHistoryExpiration );
}
STDMETHODIMP CNntpVirtualServer::put_HistoryExpiration ( long lHistoryExpiration )
{
return StdPropertyPut ( &m_dwHistoryExpiration, lHistoryExpiration, &m_bvChangedFields, CHNG_HISTORYEXPIRATION );
}
STDMETHODIMP CNntpVirtualServer::get_HonorClientMsgIDs ( BOOL * pfHonorClientMsgIDs )
{
return StdPropertyGet ( m_fHonorClientMsgIDs, pfHonorClientMsgIDs );
}
STDMETHODIMP CNntpVirtualServer::put_HonorClientMsgIDs ( BOOL fHonorClientMsgIDs )
{
return StdPropertyPut ( &m_fHonorClientMsgIDs, fHonorClientMsgIDs, &m_bvChangedFields, CHNG_HONORCLIENTMSGIDS );
}
STDMETHODIMP CNntpVirtualServer::get_SmtpServer ( BSTR * pstrSmtpServer )
{
return StdPropertyGet ( m_strSmtpServer, pstrSmtpServer );
}
STDMETHODIMP CNntpVirtualServer::put_SmtpServer ( BSTR strSmtpServer )
{
return StdPropertyPut ( &m_strSmtpServer, strSmtpServer, &m_bvChangedFields, CHNG_SMTPSERVER );
}
STDMETHODIMP CNntpVirtualServer::get_AdminEmail ( BSTR * pstrAdminEmail )
{
return StdPropertyGet ( m_strAdminEmail, pstrAdminEmail );
}
STDMETHODIMP CNntpVirtualServer::put_AdminEmail ( BSTR strAdminEmail )
{
return StdPropertyPut ( &m_strAdminEmail, strAdminEmail, &m_bvChangedFields2, CHNG2_ADMINEMAIL );
}
STDMETHODIMP CNntpVirtualServer::get_AllowClientPosts ( BOOL * pfAllowClientPosts )
{
return StdPropertyGet ( m_fAllowClientPosts, pfAllowClientPosts );
}
STDMETHODIMP CNntpVirtualServer::put_AllowClientPosts ( BOOL fAllowClientPosts )
{
return StdPropertyPut ( &m_fAllowClientPosts, fAllowClientPosts, &m_bvChangedFields, CHNG_ALLOWCLIENTPOSTS );
}
STDMETHODIMP CNntpVirtualServer::get_AllowFeedPosts ( BOOL * pfAllowFeedPosts )
{
return StdPropertyGet ( m_fAllowFeedPosts, pfAllowFeedPosts );
}
STDMETHODIMP CNntpVirtualServer::put_AllowFeedPosts ( BOOL fAllowFeedPosts )
{
return StdPropertyPut ( &m_fAllowFeedPosts, fAllowFeedPosts, &m_bvChangedFields, CHNG_ALLOWFEEDPOSTS );
}
STDMETHODIMP CNntpVirtualServer::get_AllowControlMsgs ( BOOL * pfAllowControlMsgs )
{
return StdPropertyGet ( m_fAllowControlMsgs, pfAllowControlMsgs );
}
STDMETHODIMP CNntpVirtualServer::put_AllowControlMsgs ( BOOL fAllowControlMsgs )
{
return StdPropertyPut ( &m_fAllowControlMsgs, fAllowControlMsgs, &m_bvChangedFields, CHNG_ALLOWCONTROLMSGS );
}
STDMETHODIMP CNntpVirtualServer::get_DefaultModeratorDomain ( BSTR * pstrDefaultModeratorDomain )
{
return StdPropertyGet ( m_strDefaultModeratorDomain, pstrDefaultModeratorDomain );
}
STDMETHODIMP CNntpVirtualServer::put_DefaultModeratorDomain ( BSTR strDefaultModeratorDomain )
{
return StdPropertyPut ( &m_strDefaultModeratorDomain, strDefaultModeratorDomain, &m_bvChangedFields, CHNG_DEFAULTMODERATORDOMAIN );
}
STDMETHODIMP CNntpVirtualServer::get_CommandLogMask ( long * plCommandLogMask )
{
return StdPropertyGet ( m_dwCommandLogMask, plCommandLogMask );
}
STDMETHODIMP CNntpVirtualServer::put_CommandLogMask ( long lCommandLogMask )
{
return StdPropertyPut ( &m_dwCommandLogMask, lCommandLogMask, &m_bvChangedFields, CHNG_COMMANDLOGMASK );
}
STDMETHODIMP CNntpVirtualServer::get_DisableNewnews ( BOOL * pfDisableNewnews )
{
return StdPropertyGet ( m_fDisableNewnews, pfDisableNewnews );
}
STDMETHODIMP CNntpVirtualServer::put_DisableNewnews ( BOOL fDisableNewnews )
{
return StdPropertyPut ( &m_fDisableNewnews, fDisableNewnews, &m_bvChangedFields, CHNG_DISABLENEWNEWS );
}
STDMETHODIMP CNntpVirtualServer::get_ExpireRunFrequency ( long * plExpireRunFrequency )
{
return StdPropertyGet ( m_dwExpireRunFrequency, plExpireRunFrequency );
}
STDMETHODIMP CNntpVirtualServer::put_ExpireRunFrequency ( long lExpireRunFrequency )
{
return StdPropertyPut ( &m_dwExpireRunFrequency, lExpireRunFrequency, &m_bvChangedFields, CHNG_NEWSCRAWLERTIME );
}
STDMETHODIMP CNntpVirtualServer::get_ShutdownLatency ( long * plShutdownLatency )
{
return StdPropertyGet ( m_dwShutdownLatency, plShutdownLatency );
}
STDMETHODIMP CNntpVirtualServer::put_ShutdownLatency ( long lShutdownLatency )
{
return StdPropertyPut ( &m_dwShutdownLatency, lShutdownLatency, &m_bvChangedFields, CHNG_SHUTDOWNLATENCY );
}
STDMETHODIMP CNntpVirtualServer::get_ClientPostHardLimit ( long * plClientPostHardLimit )
{
return StdPropertyGet ( m_dwClientPostHardLimit, plClientPostHardLimit );
}
STDMETHODIMP CNntpVirtualServer::put_ClientPostHardLimit ( long lClientPostHardLimit )
{
return StdPropertyPut ( &m_dwClientPostHardLimit, lClientPostHardLimit, &m_bvChangedFields, CHNG_CLIENTPOSTHARDLIMIT );
}
STDMETHODIMP CNntpVirtualServer::get_ClientPostSoftLimit ( long * plClientPostSoftLimit )
{
return StdPropertyGet ( m_dwClientPostSoftLimit, plClientPostSoftLimit );
}
STDMETHODIMP CNntpVirtualServer::put_ClientPostSoftLimit ( long lClientPostSoftLimit )
{
return StdPropertyPut ( &m_dwClientPostSoftLimit, lClientPostSoftLimit, &m_bvChangedFields, CHNG_CLIENTPOSTSOFTLIMIT );
}
STDMETHODIMP CNntpVirtualServer::get_FeedPostHardLimit ( long * plFeedPostHardLimit )
{
return StdPropertyGet ( m_dwFeedPostHardLimit, plFeedPostHardLimit );
}
STDMETHODIMP CNntpVirtualServer::put_FeedPostHardLimit ( long lFeedPostHardLimit )
{
return StdPropertyPut ( &m_dwFeedPostHardLimit, lFeedPostHardLimit, &m_bvChangedFields, CHNG_FEEDPOSTHARDLIMIT );
}
STDMETHODIMP CNntpVirtualServer::get_FeedPostSoftLimit ( long * plFeedPostSoftLimit )
{
return StdPropertyGet ( m_dwFeedPostSoftLimit, plFeedPostSoftLimit );
}
STDMETHODIMP CNntpVirtualServer::put_FeedPostSoftLimit ( long lFeedPostSoftLimit )
{
return StdPropertyPut ( &m_dwFeedPostSoftLimit, lFeedPostSoftLimit, &m_bvChangedFields, CHNG_FEEDPOSTSOFTLIMIT );
}
STDMETHODIMP CNntpVirtualServer::get_EnableLogging ( BOOL * pfEnableLogging )
{
return StdPropertyGet ( m_fEnableLogging, pfEnableLogging );
}
STDMETHODIMP CNntpVirtualServer::put_EnableLogging ( BOOL fEnableLogging )
{
return StdPropertyPut ( &m_fEnableLogging, fEnableLogging, &m_bvChangedFields2, CHNG2_ENABLELOGGING );
}
// Service-specific properties:
STDMETHODIMP CNntpVirtualServer::get_Organization ( BSTR * pstrOrganization )
{
return StdPropertyGet ( m_strOrganization, pstrOrganization );
}
STDMETHODIMP CNntpVirtualServer::put_Organization ( BSTR strOrganization )
{
return StdPropertyPut ( &m_strOrganization, strOrganization, &m_bvChangedFields, CHNG_ORGANIZATION );
}
STDMETHODIMP CNntpVirtualServer::get_UucpName ( BSTR * pstrUucpName )
{
return StdPropertyGet ( m_strUucpName, pstrUucpName );
}
STDMETHODIMP CNntpVirtualServer::put_UucpName ( BSTR strUucpName )
{
return StdPropertyPut ( &m_strUucpName, strUucpName, &m_bvChangedFields, CHNG_UUCPNAME );
}
STDMETHODIMP CNntpVirtualServer::get_GroupHelpFile ( BSTR * pstrGroupHelpFile )
{
return StdPropertyGet ( m_strGroupHelpFile, pstrGroupHelpFile );
}
STDMETHODIMP CNntpVirtualServer::put_GroupHelpFile ( BSTR strGroupHelpFile )
{
return StdPropertyPut ( &m_strGroupHelpFile, strGroupHelpFile, &m_bvChangedFields, CHNG_GROUPHELPFILE );
}
STDMETHODIMP CNntpVirtualServer::get_GroupListFile ( BSTR * pstrGroupListFile )
{
return StdPropertyGet ( m_strGroupListFile, pstrGroupListFile );
}
STDMETHODIMP CNntpVirtualServer::put_GroupListFile ( BSTR strGroupListFile )
{
return StdPropertyPut ( &m_strGroupListFile, strGroupListFile, &m_bvChangedFields, CHNG_GROUPLISTFILE );
}
STDMETHODIMP CNntpVirtualServer::get_GroupVarListFile( BSTR *pstrGroupListFile )
{
return StdPropertyGet( m_strGroupVarListFile, pstrGroupListFile );
}
STDMETHODIMP CNntpVirtualServer::put_GroupVarListFile( BSTR strGroupVarListFile )
{
return StdPropertyPut ( &m_strGroupVarListFile, strGroupVarListFile, &m_bvChangedFields, CHNG_GROUPLISTFILE );
}
STDMETHODIMP CNntpVirtualServer::get_ArticleTableFile ( BSTR * pstrArticleTableFile )
{
return StdPropertyGet ( m_strArticleTableFile, pstrArticleTableFile );
}
STDMETHODIMP CNntpVirtualServer::put_ArticleTableFile ( BSTR strArticleTableFile )
{
return StdPropertyPut ( &m_strArticleTableFile, strArticleTableFile, &m_bvChangedFields, CHNG_ARTICLETABLEFILE );
}
STDMETHODIMP CNntpVirtualServer::get_HistoryTableFile ( BSTR * pstrHistoryTableFile )
{
return StdPropertyGet ( m_strHistoryTableFile, pstrHistoryTableFile );
}
STDMETHODIMP CNntpVirtualServer::put_HistoryTableFile ( BSTR strHistoryTableFile )
{
return StdPropertyPut ( &m_strHistoryTableFile, strHistoryTableFile, &m_bvChangedFields, CHNG_HISTORYTABLEFILE );
}
STDMETHODIMP CNntpVirtualServer::get_ModeratorFile ( BSTR * pstrModeratorFile )
{
return StdPropertyGet ( m_strModeratorFile, pstrModeratorFile );
}
STDMETHODIMP CNntpVirtualServer::put_ModeratorFile ( BSTR strModeratorFile )
{
return StdPropertyPut ( &m_strModeratorFile, strModeratorFile, &m_bvChangedFields, CHNG_MODERATORFILE );
}
STDMETHODIMP CNntpVirtualServer::get_XOverTableFile ( BSTR * pstrXOverTableFile )
{
return StdPropertyGet ( m_strXOverTableFile, pstrXOverTableFile );
}
STDMETHODIMP CNntpVirtualServer::put_XOverTableFile ( BSTR strXOverTableFile )
{
return StdPropertyPut ( &m_strXOverTableFile, strXOverTableFile, &m_bvChangedFields, CHNG_XOVERTABLEFILE );
}
STDMETHODIMP CNntpVirtualServer::get_AutoStart ( BOOL * pfAutoStart )
{
return StdPropertyGet ( m_fAutoStart, pfAutoStart );
}
STDMETHODIMP CNntpVirtualServer::put_AutoStart ( BOOL fAutoStart )
{
return StdPropertyPut ( &m_fAutoStart, fAutoStart, &m_bvChangedFields, CHNG_AUTOSTART );
}
STDMETHODIMP CNntpVirtualServer::get_Comment ( BSTR * pstrComment )
{
if ( m_strComment.Length() == 0 ) return StdPropertyGet( m_strUucpName, pstrComment );
else return StdPropertyGet ( m_strComment, pstrComment );
}
STDMETHODIMP CNntpVirtualServer::put_Comment ( BSTR strComment )
{
return StdPropertyPut ( &m_strComment, strComment, &m_bvChangedFields, CHNG_COMMENT );
}
STDMETHODIMP CNntpVirtualServer::get_Bindings ( INntpServerBindings ** ppBindings )
{
TraceQuietEnter ( "CNntpVirtualServer::get_Bindings" );
HRESULT hr = NOERROR;
if ( !m_pBindings ) {
ErrorTrace ( 0, "Didn't call get first" );
hr = NntpCreateException ( IDS_NNTPEXCEPTION_DIDNT_CALL_GET );
goto Exit;
}
else {
hr = m_pBindings->QueryInterface ( IID_INntpServerBindings, (void **) ppBindings );
_ASSERT ( SUCCEEDED(hr) );
}
Exit:
TRACE_HRESULT(hr);
TraceFunctLeave ();
return hr;
}
STDMETHODIMP CNntpVirtualServer::get_BindingsDispatch ( IDispatch ** ppBindings )
{
HRESULT hr = NOERROR;
CComPtr<INntpServerBindings> pBindings;
hr = get_Bindings ( &pBindings );
if ( FAILED(hr) ) {
goto Exit;
}
hr = pBindings->QueryInterface ( IID_IDispatch, (void **) ppBindings );
if ( FAILED(hr) ) {
goto Exit;
}
Exit:
return hr;
}
STDMETHODIMP CNntpVirtualServer::get_SecurePort ( long * pdwSecurePort )
{
return StdPropertyGet ( m_dwSecurePort, pdwSecurePort );
}
STDMETHODIMP CNntpVirtualServer::put_SecurePort ( long dwSecurePort )
{
return StdPropertyPut ( &m_dwSecurePort, dwSecurePort, &m_bvChangedFields, CHNG_SECUREPORT );
}
STDMETHODIMP CNntpVirtualServer::get_MaxConnections ( long * pdwMaxConnections )
{
return StdPropertyGet ( m_dwMaxConnections, pdwMaxConnections );
}
STDMETHODIMP CNntpVirtualServer::put_MaxConnections ( long dwMaxConnections )
{
return StdPropertyPut ( &m_dwMaxConnections, dwMaxConnections, &m_bvChangedFields, CHNG_MAXCONNECTIONS );
}
STDMETHODIMP CNntpVirtualServer::get_ConnectionTimeout ( long * pdwConnectionTimeout )
{
return StdPropertyGet ( m_dwConnectionTimeout, pdwConnectionTimeout );
}
STDMETHODIMP CNntpVirtualServer::put_ConnectionTimeout ( long dwConnectionTimeout )
{
return StdPropertyPut ( &m_dwConnectionTimeout, dwConnectionTimeout, &m_bvChangedFields2, CHNG2_CONNECTIONTIMEOUT );
}
STDMETHODIMP CNntpVirtualServer::get_AnonymousUserName ( BSTR * pstrAnonymousUserName )
{
return StdPropertyGet ( m_strAnonymousUserName, pstrAnonymousUserName );
}
STDMETHODIMP CNntpVirtualServer::put_AnonymousUserName ( BSTR strAnonymousUserName )
{
return StdPropertyPut ( &m_strAnonymousUserName, strAnonymousUserName, &m_bvChangedFields2, CHNG2_ANONYMOUSUSERNAME );
}
STDMETHODIMP CNntpVirtualServer::get_AnonymousUserPass ( BSTR * pstrAnonymousUserPass )
{
return StdPropertyGet ( m_strAnonymousUserPass, pstrAnonymousUserPass );
}
STDMETHODIMP CNntpVirtualServer::put_AnonymousUserPass ( BSTR strAnonymousUserPass )
{
return StdPropertyPut ( &m_strAnonymousUserPass, strAnonymousUserPass, &m_bvChangedFields2, CHNG2_ANONYMOUSUSERPASS );
}
STDMETHODIMP CNntpVirtualServer::get_AutoSyncPassword ( BOOL * pfAutoSyncPassword )
{
return StdPropertyGet ( m_fAutoSyncPassword, pfAutoSyncPassword );
}
STDMETHODIMP CNntpVirtualServer::put_AutoSyncPassword ( BOOL fAutoSyncPassword )
{
return StdPropertyPut ( &m_fAutoSyncPassword, fAutoSyncPassword, &m_bvChangedFields2, CHNG2_AUTOSYNCPASSWORD );
}
STDMETHODIMP CNntpVirtualServer::get_PickupDirectory ( BSTR * pstrPickupDirectory )
{
return StdPropertyGet ( m_strPickupDirectory, pstrPickupDirectory );
}
STDMETHODIMP CNntpVirtualServer::put_PickupDirectory ( BSTR strPickupDirectory )
{
return StdPropertyPut ( &m_strPickupDirectory, strPickupDirectory, &m_bvChangedFields2, CHNG2_PICKUPDIRECTORY );
}
STDMETHODIMP CNntpVirtualServer::get_FailedPickupDirectory ( BSTR * pstrFailedPickupDirectory )
{
return StdPropertyGet ( m_strFailedPickupDirectory, pstrFailedPickupDirectory );
}
STDMETHODIMP CNntpVirtualServer::put_FailedPickupDirectory ( BSTR strFailedPickupDirectory )
{
return StdPropertyPut ( &m_strFailedPickupDirectory, strFailedPickupDirectory, &m_bvChangedFields2, CHNG2_FAILEDPICKUPDIRECTORY );
}
STDMETHODIMP CNntpVirtualServer::get_AuthAnonymous ( BOOL * pfAuthAnonymous )
{
return StdPropertyGetBit ( m_bvAuthorization, MD_AUTH_ANONYMOUS, pfAuthAnonymous );
}
STDMETHODIMP CNntpVirtualServer::put_AuthAnonymous ( BOOL fAuthAnonymous )
{
return StdPropertyPutBit ( &m_bvAuthorization, MD_AUTH_ANONYMOUS, fAuthAnonymous );
}
STDMETHODIMP CNntpVirtualServer::get_AuthBasic ( BOOL * pfAuthBasic )
{
return StdPropertyGetBit ( m_bvAuthorization, MD_AUTH_BASIC, pfAuthBasic );
}
STDMETHODIMP CNntpVirtualServer::put_AuthBasic ( BOOL fAuthBasic )
{
return StdPropertyPutBit ( &m_bvAuthorization, MD_AUTH_BASIC, fAuthBasic );
}
STDMETHODIMP CNntpVirtualServer::get_AuthMCISBasic ( BOOL * pfAuthMCISBasic )
{
*pfAuthMCISBasic = FALSE;
return NOERROR;
// return StdPropertyGetBit ( m_bvAuthorization, MD_AUTH_MCIS_BASIC, pfAuthMCISBasic );
}
STDMETHODIMP CNntpVirtualServer::put_AuthMCISBasic ( BOOL fAuthMCISBasic )
{
return NOERROR;
// return StdPropertyPutBit ( &m_bvAuthorization, MD_AUTH_MCIS_BASIC, fAuthMCISBasic );
}
STDMETHODIMP CNntpVirtualServer::get_AuthNT ( BOOL * pfAuthNT )
{
return StdPropertyGetBit ( m_bvAuthorization, MD_AUTH_NT, pfAuthNT );
}
STDMETHODIMP CNntpVirtualServer::put_AuthNT ( BOOL fAuthNT )
{
return StdPropertyPutBit ( &m_bvAuthorization, MD_AUTH_NT, fAuthNT );
}
STDMETHODIMP CNntpVirtualServer::get_SSLNegotiateCert ( BOOL * pfNegotiateCert )
{
return StdPropertyGetBit ( m_bvSslAccess, MD_ACCESS_NEGO_CERT, pfNegotiateCert );
}
STDMETHODIMP CNntpVirtualServer::put_SSLNegotiateCert ( BOOL fNegotiateCert )
{
return StdPropertyPutBit ( &m_bvSslAccess, MD_ACCESS_NEGO_CERT, fNegotiateCert ); // , &m_bvChangedFields2, CHNG2_SSLACCESS );
}
STDMETHODIMP CNntpVirtualServer::get_SSLRequireCert ( BOOL * pfRequireCert )
{
return StdPropertyGetBit ( m_bvSslAccess, MD_ACCESS_REQUIRE_CERT, pfRequireCert );
}
STDMETHODIMP CNntpVirtualServer::put_SSLRequireCert ( BOOL fRequireCert )
{
return StdPropertyPutBit ( &m_bvSslAccess, MD_ACCESS_REQUIRE_CERT, fRequireCert ); // , &m_bvChangedFields2, CHNG2_SSLACCESS );
}
STDMETHODIMP CNntpVirtualServer::get_SSLMapCert ( BOOL * pfMapCert )
{
return StdPropertyGetBit ( m_bvSslAccess, MD_ACCESS_MAP_CERT, pfMapCert );
}
STDMETHODIMP CNntpVirtualServer::put_SSLMapCert ( BOOL fMapCert )
{
return StdPropertyPutBit ( &m_bvSslAccess, MD_ACCESS_MAP_CERT, fMapCert ); // , &m_bvChangedFields2, CHNG2_SSLACCESS );
}
/*
STDMETHODIMP CNntpVirtualServer::get_AuthenticationProviders ( SAFEARRAY ** ppsastrProviders )
{
return StdPropertyGet ( &m_mszProviders, ppsastrProviders );
}
STDMETHODIMP CNntpVirtualServer::put_AuthenticationProviders ( SAFEARRAY * psastrProviders )
{
return StdPropertyPut ( &m_mszProviders, psastrProviders );
}
STDMETHODIMP CNntpVirtualServer::get_AuthenticationProvidersVariant ( SAFEARRAY ** ppsavarAuthProviders )
{
HRESULT hr;
SAFEARRAY * psastrAuthProviders = NULL;
hr = get_AuthenticationProviders ( &psastrAuthProviders );
if ( FAILED(hr) ) {
goto Exit;
}
hr = StringArrayToVariantArray ( psastrAuthProviders, ppsavarAuthProviders );
Exit:
if ( psastrAuthProviders ) {
SafeArrayDestroy ( psastrAuthProviders );
}
return hr;
}
STDMETHODIMP CNntpVirtualServer::put_AuthenticationProvidersVariant ( SAFEARRAY * psavarAuthProviders )
{
HRESULT hr;
SAFEARRAY * psastrAuthProviders = NULL;
hr = VariantArrayToStringArray ( psavarAuthProviders, &psastrAuthProviders );
if ( FAILED(hr) ) {
goto Exit;
}
hr = put_AuthenticationProviders ( psastrAuthProviders );
Exit:
if ( psastrAuthProviders ) {
SafeArrayDestroy ( psastrAuthProviders );
}
return hr;
}
*/
STDMETHODIMP CNntpVirtualServer::get_Administrators ( SAFEARRAY ** ppsastrAdmins )
{
TraceFunctEnter ( "CNntpVS::get_Administrators" );
HRESULT hr = NOERROR;
if ( m_psaAdmins ) {
hr = SafeArrayCopy ( m_psaAdmins, ppsastrAdmins );
}
else {
*ppsastrAdmins = NULL;
hr = NOERROR;
}
TraceFunctLeave ();
return hr;
}
STDMETHODIMP CNntpVirtualServer::put_Administrators ( SAFEARRAY * psastrAdmins )
{
TraceFunctEnter ( "CNntpVS::put_Administrators" );
HRESULT hr = NOERROR;
if ( m_psaAdmins ) {
SafeArrayDestroy ( m_psaAdmins );
}
if ( psastrAdmins ) {
hr = SafeArrayCopy ( psastrAdmins, &m_psaAdmins );
}
else {
m_psaAdmins = NULL;
hr = NOERROR;
}
m_bvChangedFields2 |= CHNG2_ADMINACL;
TraceFunctLeave ();
return hr;
}
STDMETHODIMP CNntpVirtualServer::get_AdministratorsVariant ( SAFEARRAY ** ppsavarAdmins )
{
HRESULT hr;
SAFEARRAY * psastrAdmins = NULL;
hr = get_Administrators ( &psastrAdmins );
if ( FAILED(hr) ) {
goto Exit;
}
hr = StringArrayToVariantArray ( psastrAdmins, ppsavarAdmins );
Exit:
if ( psastrAdmins ) {
SafeArrayDestroy ( psastrAdmins );
}
return hr;
}
STDMETHODIMP CNntpVirtualServer::put_AdministratorsVariant ( SAFEARRAY * psavarAdmins )
{
HRESULT hr;
SAFEARRAY * psastrAdmins = NULL;
hr = VariantArrayToStringArray ( psavarAdmins, &psastrAdmins );
if ( FAILED(hr) ) {
goto Exit;
}
hr = put_Administrators ( psastrAdmins );
Exit:
if ( psastrAdmins ) {
SafeArrayDestroy ( psastrAdmins );
}
return hr;
}
STDMETHODIMP CNntpVirtualServer::get_ClusterEnabled ( BOOL *pfClusterEnabled )
{
return StdPropertyGet ( m_fClusterEnabled, pfClusterEnabled );
}
STDMETHODIMP CNntpVirtualServer::put_ClusterEnabled ( BOOL fClusterEnabled )
{
return StdPropertyPut ( &m_fClusterEnabled, fClusterEnabled, &m_bvChangedFields2, CHNG2_CLUSTERENABLED);
}
STDMETHODIMP CNntpVirtualServer::get_State ( NNTP_SERVER_STATE * pState )
{
if ( pState == NULL ) {
return E_POINTER;
}
*pState = m_State;
return NOERROR;
}
STDMETHODIMP CNntpVirtualServer::get_Win32ErrorCode ( long * plWin32ErrorCode )
{
return StdPropertyGet ( m_dwWin32ErrorCode, plWin32ErrorCode );
}
/*
STDMETHODIMP CNntpVirtualServer::get_DisplayName ( BSTR * pstrDisplayName )
{
return StdPropertyGet ( m_strDisplayName, pstrDisplayName );
}
STDMETHODIMP CNntpVirtualServer::put_DisplayName ( BSTR strDisplayName )
{
return StdPropertyPut ( &m_strDisplayName, strDisplayName );
}
STDMETHODIMP CNntpVirtualServer::get_ErrorControl ( BOOL * pfErrorControl )
{
return StdPropertyGet ( m_fErrorControl, pfErrorControl );
}
STDMETHODIMP CNntpVirtualServer::put_ErrorControl ( BOOL fErrorControl )
{
return StdPropertyPut ( &m_fErrorControl, fErrorControl );
}
STDMETHODIMP CNntpVirtualServer::get_CleanBoot ( BOOL * pfCleanBoot )
{
return StdPropertyGet ( m_fCleanBoot, pfCleanBoot );
}
STDMETHODIMP CNntpVirtualServer::put_CleanBoot ( BOOL fCleanBoot )
{
return StdPropertyPut ( &m_fCleanBoot, fCleanBoot );
}
STDMETHODIMP CNntpVirtualServer::get_EncryptionCapabilitiesMask ( long * plEncryptionCapabilitiesMask )
{
return StdPropertyGet ( m_dwEncryptionCapabilities, plEncryptionCapabilitiesMask );
}
STDMETHODIMP CNntpVirtualServer::put_EncryptionCapabilitiesMask ( long lEncryptionCapabilitiesMask )
{
return StdPropertyPut ( &m_dwEncryptionCapabilities, lEncryptionCapabilitiesMask, &m_bvChangedFields, CHNG_ENCRYPTIONCAPABILITIES );
}
*/
//////////////////////////////////////////////////////////////////////
// Methods:
//////////////////////////////////////////////////////////////////////
//$-------------------------------------------------------------------
//
// CNntpVirtualServer::Get
//
// Description:
//
// Gets server properties from the metabase.
//
// Parameters:
//
// (property) m_strServer
// (property) m_dwServiceInstance - which NNTP to talk to.
// pErr - Resulting error code. This can be translated to a
// string through the INntpAdmin interface.
//
// Returns:
//
// E_POINTER, DISP_E_EXCEPTION, E_OUTOFMEMORY or NOERROR.
// Additional error conditions are returned through the pErr value.
//
//--------------------------------------------------------------------
STDMETHODIMP CNntpVirtualServer::Get ( )
{
TraceFunctEnter ( "CNntpVirtualServer::Get" );
HRESULT hr = NOERROR;
CComPtr<IMSAdminBase> pmetabase;
CComObject<CNntpServerBindings> * pBindings = NULL;
// Validate Server & Service Instance:
// Create the bindings collection:
m_pBindings.Release ();
hr = CComObject<CNntpServerBindings>::CreateInstance ( &pBindings );
if ( FAILED(hr) ) {
FatalTrace ( (LPARAM) this, "Could not create bindings collection" );
goto Exit;
}
hr = pBindings->QueryInterface ( IID_INntpServerBindings, (void **) &m_pBindings );
_ASSERT ( SUCCEEDED(hr) );
if ( FAILED(hr) ) {
goto Exit;
}
m_pPrivateBindings = pBindings;
// Talk to the metabase:
hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
if ( FAILED(hr) ) {
goto Exit;
}
hr = GetPropertiesFromMetabase ( pmetabase );
if ( FAILED(hr) ) {
goto Exit;
}
StateTrace ( 0, "Successfully got service properties" );
m_fGotProperties = TRUE;
m_bvChangedFields = 0;
m_bvChangedFields2 = 0;
Exit:
TRACE_HRESULT(hr);
TraceFunctLeave ();
return hr;
// CComPtr automatically releases the metabase handle.
}
//$-------------------------------------------------------------------
//
// CNntpVirtualServer::Set
//
// Description:
//
// Sends server properties to the metabase.
//
// Parameters:
//
// (property) m_strServer
// fFailIfChanged - return an error if the metabase has changed?
// pErr - Resulting error code. This can be translated to a
// string through the INntpAdmin interface.
//
// Returns:
//
// E_POINTER, DISP_E_EXCEPTION, E_OUTOFMEMORY or NOERROR.
// Additional error conditions are returned through the pErr value.
//
//--------------------------------------------------------------------
STDMETHODIMP CNntpVirtualServer::Set ( BOOL fFailIfChanged)
{
TraceFunctEnter ( "CNntpVirtualServer::Set" );
HRESULT hr = NOERROR;
CComPtr<IMSAdminBase> pmetabase;
// Make sure the client call Get first:
if ( !m_fGotProperties ) {
ErrorTrace ( 0, "Didn't call get first" );
return NntpCreateException ( IDS_NNTPEXCEPTION_DIDNT_CALL_GET );
}
// Validate Server & Service Instance:
if ( m_dwServiceInstance == 0 ) {
return NntpCreateException ( IDS_NNTPEXCEPTION_SERVICE_INSTANCE_CANT_BE_ZERO );
}
if ( !m_fGotProperties ) {
return NntpCreateException ( IDS_NNTPEXCEPTION_DIDNT_CALL_GET );
}
// Validate data members:
if ( !ValidateStrings () ) {
// !!!magnush - what about the case when any strings are NULL?
hr = E_OUTOFMEMORY;
goto Exit;
}
if ( !ValidateProperties ( ) ) {
hr = RETURNCODETOHRESULT ( ERROR_INVALID_PARAMETER );
goto Exit;
}
hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
if ( FAILED(hr) ) {
goto Exit;
}
hr = SendPropertiesToMetabase ( fFailIfChanged, pmetabase );
if ( FAILED(hr) ) {
goto Exit;
}
StateTrace ( 0, "Successfully set service properties" );
Exit:
TRACE_HRESULT(hr);
TraceFunctLeave ();
return hr;
}
HRESULT CNntpVirtualServer::ControlService (
IMSAdminBase * pMetabase,
DWORD ControlCode,
DWORD dwDesiredState,
DWORD dwPendingState
)
{
TraceFunctEnter ( "CNntpVirtualServer::ControlService" );
HRESULT hr = NOERROR;
DWORD dwCurrentState = dwPendingState;
DWORD dwOldState = dwPendingState;
DWORD dwSleepTotal = 0;
hr = CheckServiceState ( pMetabase, &dwCurrentState );
BAIL_ON_FAILURE(hr);
if ( dwCurrentState == dwDesiredState ) {
// Nothing to do...
goto Exit;
}
dwOldState = dwCurrentState;
//
// Special case: trying to start a paused service:
//
if ( dwDesiredState == MD_SERVER_STATE_STARTED &&
dwCurrentState == MD_SERVER_STATE_PAUSED ) {
ControlCode = MD_SERVER_COMMAND_CONTINUE;
dwPendingState = MD_SERVER_STATE_CONTINUING;
}
hr = WriteStateCommand ( pMetabase, ControlCode );
BAIL_ON_FAILURE(hr);
for ( dwSleepTotal = 0, dwCurrentState = dwPendingState;
(dwCurrentState == dwPendingState || dwCurrentState == dwOldState) && (dwSleepTotal < MAX_SLEEP_INST);
dwSleepTotal += SLEEP_INTERVAL
) {
Sleep ( SLEEP_INTERVAL );
hr = CheckServiceState ( pMetabase, &dwCurrentState );
BAIL_ON_FAILURE(hr);
if ( m_dwWin32ErrorCode != NOERROR ) {
//
// The service gave an error code.
//
break;
}
}
if ( dwSleepTotal >= MAX_SLEEP_INST ) {
hr = HRESULT_FROM_WIN32 ( ERROR_SERVICE_REQUEST_TIMEOUT );
goto Exit;
}
Exit:
m_State = TranslateServerState ( dwCurrentState );
TraceFunctLeave ();
return hr;
}
HRESULT CNntpVirtualServer::WriteStateCommand ( IMSAdminBase * pMetabase, DWORD ControlCode )
{
HRESULT hr = NOERROR;
CMetabaseKey metabase ( pMetabase );
WCHAR wszInstancePath [ METADATA_MAX_NAME_LEN ];
GetMDInstancePath ( wszInstancePath, m_dwServiceInstance );
hr = metabase.Open ( wszInstancePath, METADATA_PERMISSION_WRITE );
hr = StdPutMetabaseProp ( &metabase, MD_WIN32_ERROR, NOERROR, _T(""), IIS_MD_UT_SERVER, METADATA_VOLATILE );
BAIL_ON_FAILURE (hr);
hr = StdPutMetabaseProp ( &metabase, MD_SERVER_COMMAND, ControlCode );
BAIL_ON_FAILURE (hr);
hr = metabase.Save ();
BAIL_ON_FAILURE(hr);
Exit:
return hr;
}
HRESULT CNntpVirtualServer::CheckServiceState ( IMSAdminBase * pMetabase, DWORD * pdwState )
{
HRESULT hr = NOERROR;
CMetabaseKey metabase ( pMetabase );
WCHAR wszInstancePath [ METADATA_MAX_NAME_LEN ];
*pdwState = MD_SERVER_STATE_INVALID;
GetMDInstancePath ( wszInstancePath, m_dwServiceInstance );
hr = metabase.Open ( wszInstancePath );
BAIL_ON_FAILURE(hr);
m_dwWin32ErrorCode = NOERROR;
metabase.GetDword ( MD_SERVER_STATE, pdwState );
metabase.GetDword ( MD_WIN32_ERROR, &m_dwWin32ErrorCode );
Exit:
return hr;
}
STDMETHODIMP CNntpVirtualServer::Start ( )
{
TraceFunctEnter ( "CNntpVirtualServer::Start" );
HRESULT hr = NOERROR;
CComPtr<IMSAdminBase> pmetabase;
hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
if ( FAILED(hr) ) {
goto Exit;
}
hr = ControlService (
pmetabase,
MD_SERVER_COMMAND_START,
MD_SERVER_STATE_STARTED,
MD_SERVER_STATE_STARTING
);
Exit:
TraceFunctLeave ();
return hr;
}
STDMETHODIMP CNntpVirtualServer::Pause ( )
{
TraceFunctEnter ( "CNntpVirtualServer::Start" );
HRESULT hr = NOERROR;
CComPtr<IMSAdminBase> pmetabase;
hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
if ( FAILED(hr) ) {
goto Exit;
}
hr = ControlService (
pmetabase,
MD_SERVER_COMMAND_PAUSE,
MD_SERVER_STATE_PAUSED,
MD_SERVER_STATE_PAUSING
);
Exit:
TraceFunctLeave ();
return hr;
}
STDMETHODIMP CNntpVirtualServer::Continue ( )
{
TraceFunctEnter ( "CNntpVirtualServer::Start" );
HRESULT hr = NOERROR;
CComPtr<IMSAdminBase> pmetabase;
hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
if ( FAILED(hr) ) {
goto Exit;
}
hr = ControlService (
pmetabase,
MD_SERVER_COMMAND_CONTINUE,
MD_SERVER_STATE_STARTED,
MD_SERVER_STATE_CONTINUING
);
Exit:
TraceFunctLeave ();
return hr;
}
STDMETHODIMP CNntpVirtualServer::Stop ( )
{
TraceFunctEnter ( "CNntpVirtualServer::Start" );
HRESULT hr = NOERROR;
CComPtr<IMSAdminBase> pmetabase;
hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase );
if ( FAILED(hr) ) {
goto Exit;
}
hr = ControlService (
pmetabase,
MD_SERVER_COMMAND_STOP,
MD_SERVER_STATE_STOPPED,
MD_SERVER_STATE_STOPPING
);
Exit:
TraceFunctLeave ();
return hr;
}
//$-------------------------------------------------------------------
//
// CNntpVirtualServer::GetPropertiesFromMetabase
//
// Description:
//
// Asks the metabase for each property in this class.
// This class's properties come from /LM/NntpSvc/
//
// Parameters:
//
// pMetabase - The metabase object
// pErr - Resulting error code.
//
// Returns:
//
// E_OUTOFMEMORY or an error code in pErr.
//
//--------------------------------------------------------------------
HRESULT CNntpVirtualServer::GetPropertiesFromMetabase ( IMSAdminBase * pMetabase)
{
TraceFunctEnter ( "CNntpVirtualServer::GetPropertiesFromMetabase" );
HRESULT hr = NOERROR;
CMetabaseKey metabase ( pMetabase );
WCHAR wszInstancePath [ METADATA_MAX_NAME_LEN ];
DWORD dwServerState = MD_SERVER_STATE_STOPPED;
CMultiSz mszBindings;
CMultiSz mszSecureBindings;
PSECURITY_DESCRIPTOR pSD = NULL;
DWORD cbSD = 0;
BOOL fRet;
GetMDInstancePath ( wszInstancePath, m_dwServiceInstance );
hr = metabase.Open ( wszInstancePath );
if ( FAILED(hr) ) {
ErrorTraceX ( (LPARAM) this, "Failed to open service instance key, %x", hr );
// Return some kind of error code here:
// hr = NntpCreateExceptionFromWin32Error ( hr );
goto Exit;
}
fRet = TRUE;
// Overridable server properties:
fRet = StdGetMetabaseProp ( &metabase, MD_ARTICLE_TIME_LIMIT, NNTP_DEF_ARTICLETIMELIMIT, &m_dwArticleTimeLimit ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_HISTORY_EXPIRATION, NNTP_DEF_HISTORYEXPIRATION, &m_dwHistoryExpiration ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_HONOR_CLIENT_MSGIDS, NNTP_DEF_HONORCLIENTMSGIDS, &m_fHonorClientMsgIDs ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_SMTP_SERVER, NNTP_DEF_SMTPSERVER, &m_strSmtpServer ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_ADMIN_EMAIL, NNTP_DEF_ADMIN_EMAIL, &m_strAdminEmail ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_ALLOW_CLIENT_POSTS, NNTP_DEF_ALLOWCLIENTPOSTS, &m_fAllowClientPosts ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_ALLOW_FEED_POSTS, NNTP_DEF_ALLOWFEEDPOSTS, &m_fAllowFeedPosts ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_ALLOW_CONTROL_MSGS, NNTP_DEF_ALLOWCONTROLMSGS, &m_fAllowControlMsgs ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_DEFAULT_MODERATOR, NNTP_DEF_DEFAULTMODERATORDOMAIN, &m_strDefaultModeratorDomain ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_NNTP_COMMAND_LOG_MASK, NNTP_DEF_COMMANDLOGMASK, &m_dwCommandLogMask ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_DISABLE_NEWNEWS, NNTP_DEF_DISABLENEWNEWS, &m_fDisableNewnews ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_NEWS_CRAWLER_TIME, NNTP_DEF_NEWSCRAWLERTIME, &m_dwExpireRunFrequency ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_SHUTDOWN_LATENCY, NNTP_DEF_SHUTDOWNLATENCY, &m_dwShutdownLatency ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_LOG_TYPE, NNTP_DEF_ENABLE_LOGGING, &m_fEnableLogging ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_CLIENT_POST_HARD_LIMIT, NNTP_DEF_CLIENTPOSTHARDLIMIT, &m_dwClientPostHardLimit ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_CLIENT_POST_SOFT_LIMIT, NNTP_DEF_CLIENTPOSTSOFTLIMIT, &m_dwClientPostSoftLimit ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_FEED_POST_HARD_LIMIT, NNTP_DEF_FEEDPOSTHARDLIMIT, &m_dwFeedPostHardLimit ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_FEED_POST_SOFT_LIMIT, NNTP_DEF_FEEDPOSTSOFTLIMIT, &m_dwFeedPostSoftLimit ) && fRet;
// Service-specific properties:
fRet = StdGetMetabaseProp ( &metabase, MD_GROUP_HELP_FILE, NNTP_DEF_GROUPHELPFILE, &m_strGroupHelpFile ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_GROUP_LIST_FILE, NNTP_DEF_GROUPLISTFILE, &m_strGroupListFile ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_GROUPVAR_LIST_FILE, NNTP_DEF_GROUPVARLISTFILE, &m_strGroupVarListFile) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_ARTICLE_TABLE_FILE, NNTP_DEF_ARTICLETABLEFILE, &m_strArticleTableFile ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_HISTORY_TABLE_FILE, NNTP_DEF_HISTORYTABLEFILE, &m_strHistoryTableFile ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_MODERATOR_FILE, NNTP_DEF_MODERATORFILE, &m_strModeratorFile ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_XOVER_TABLE_FILE, NNTP_DEF_XOVERTABLEFILE, &m_strXOverTableFile ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_NNTP_UUCP_NAME, NNTP_DEF_UUCPNAME, &m_strUucpName ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_NNTP_ORGANIZATION, NNTP_DEF_ORGANIZATION, &m_strOrganization ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_SERVER_AUTOSTART, NNTP_DEF_AUTOSTART, &m_fAutoStart ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_SERVER_COMMENT, NNTP_DEF_COMMENT, &m_strComment ) && fRet;
#if 0
fRet = StdGetMetabaseProp ( &metabase, MD_SECURE_PORT, NNTP_DEF_SECUREPORT, &m_dwSecurePort ) && fRet;
#endif
fRet = StdGetMetabaseProp ( &metabase, MD_MAX_CONNECTIONS, NNTP_DEF_MAXCONNECTIONS, &m_dwMaxConnections ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_CONNECTION_TIMEOUT, NNTP_DEF_CONNECTIONTIMEOUT, &m_dwConnectionTimeout ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_ANONYMOUS_USER_NAME, NNTP_DEF_ANONYMOUSUSERNAME, &m_strAnonymousUserName ) && fRet;
if ( fRet && !StdGetMetabaseProp ( &metabase, MD_ANONYMOUS_PWD, NNTP_DEF_ANONYMOUSUSERPASS, &m_strAnonymousUserPass, _T(""), IIS_MD_UT_FILE, METADATA_INHERIT | METADATA_SECURE ) ) {
m_strAnonymousUserPass = _T("");
fRet = TRUE;
}
fRet = StdGetMetabaseProp ( &metabase, MD_ANONYMOUS_USE_SUBAUTH, FALSE, &m_fAutoSyncPassword ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_PICKUP_DIRECTORY, NNTP_DEF_PICKUPDIRECTORY, &m_strPickupDirectory ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_FAILED_PICKUP_DIRECTORY, NNTP_DEF_FAILEDPICKUPDIRECTORY, &m_strFailedPickupDirectory ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_SERVER_STATE, MD_SERVER_STATE_INVALID, &dwServerState ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_SERVER_BINDINGS, NNTP_DEF_BINDINGS, &mszBindings ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_SECURE_BINDINGS, NNTP_DEF_SECURE_BINDINGS, &mszSecureBindings ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_WIN32_ERROR, NOERROR, &m_dwWin32ErrorCode,
_T(""), IIS_MD_UT_SERVER, METADATA_VOLATILE) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_AUTHORIZATION, NNTP_DEF_AUTHORIZATION, &m_bvAuthorization ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_SSL_ACCESS_PERM, 0, &m_bvSslAccess ) && fRet;
// fRet = StdGetMetabaseProp ( &metabase, MD_NTAUTHENTICATION_PROVIDERS, NNTP_DEF_NTAUTHENTICATION_PROVIDERS, &m_mszProviders ) && fRet;
fRet = StdGetMetabaseProp ( &metabase, MD_CLUSTER_ENABLED, NNTP_DEF_CLUSTERENABLED, &m_fClusterEnabled ) && fRet;
// Get the admin ACL
pSD = NULL;
cbSD = 0;
hr = metabase.GetDataSize ( _T(""), MD_ADMIN_ACL, BINARY_METADATA, &cbSD );
if ( SUCCEEDED(hr) ) {
_ASSERT ( cbSD != 0 );
pSD = (PSECURITY_DESCRIPTOR) new char [ cbSD ];
hr = metabase.GetBinary ( MD_ADMIN_ACL, pSD, cbSD );
}
hr = NOERROR;
//
// Get the tcp access restrictions:
//
hr = m_pPrivateIpAccess->GetFromMetabase ( &metabase );
BAIL_ON_FAILURE(hr);
// Check all property strings:
// If any string is NULL, it is because we failed to allocate memory:
if ( !ValidateStrings () || !mszBindings) {
hr = E_OUTOFMEMORY;
goto Exit;
}
// We can only fail from memory allocations:
_ASSERT ( fRet );
// Extract the server state:
m_State = TranslateServerState ( dwServerState );
// Save the last changed time for this key:
m_ftLastChanged.dwHighDateTime = 0;
m_ftLastChanged.dwLowDateTime = 0;
hr = pMetabase->GetLastChangeTime ( metabase.QueryHandle(), _T(""), &m_ftLastChanged, FALSE );
if ( FAILED (hr) ) {
ErrorTraceX ( (LPARAM) this, "Failed to get last change time: %x", hr );
// Ignore this error.
hr = NOERROR;
}
metabase.Close();
// Extract the bindings:
hr = MDBindingsToIBindings ( &mszBindings, TRUE, m_pBindings );
BAIL_ON_FAILURE(hr);
hr = MDBindingsToIBindings ( &mszSecureBindings, FALSE, m_pBindings );
BAIL_ON_FAILURE(hr);
// Extract the Administrator list:
if ( m_psaAdmins ) {
SafeArrayDestroy ( m_psaAdmins );
m_psaAdmins = NULL;
}
if ( pSD ) {
hr = AclToAdministrators ( m_strServer, pSD, &m_psaAdmins );
BAIL_ON_FAILURE(hr);
}
// Validate the data received from the metabase:
_ASSERT ( ValidateStrings () );
_ASSERT ( ValidateProperties( ) );
if ( !ValidateProperties( ) ) {
CorrectProperties ();
}
Exit:
delete (char*) pSD;
TraceFunctLeave ();
return hr;
// MB automatically closes its handle
}
//$-------------------------------------------------------------------
//
// CNntpVirtualServer::SendPropertiesToMetabase
//
// Description:
//
// Saves each property to the metabase.
// This class's properties go into /LM/NntpSvc/
//
// Parameters:
//
// fFailIfChanged - Return a failure code if the metabase
// has changed since last get.
// pMetabase - the metabase object.
// pErr - resulting error code.
//
// Returns:
//
// E_OUTOFMEMORY or resulting error code in pErr.
//
//--------------------------------------------------------------------
HRESULT CNntpVirtualServer::SendPropertiesToMetabase (
BOOL fFailIfChanged,
IMSAdminBase * pMetabase
)
{
TraceFunctEnter ( "CNntpVirtualServer::SendPropertiesToMetabase" );
HRESULT hr = NOERROR;
CMetabaseKey metabase ( pMetabase );
WCHAR wszInstancePath [ METADATA_MAX_NAME_LEN ];
CMultiSz mszBindings;
CMultiSz mszSecureBindings;
BOOL fRet;
//
// Set the admin acl:
//
PSECURITY_DESCRIPTOR pSD = NULL;
DWORD cbSD = 0;
if ( m_bvChangedFields2 & CHNG2_ADMINACL ) {
if ( m_psaAdmins ) {
hr = AdministratorsToAcl ( m_strServer, m_psaAdmins, &pSD, &cbSD );
BAIL_ON_FAILURE(hr);
}
}
//
// Open the metabase key:
//
GetMDInstancePath ( wszInstancePath, m_dwServiceInstance );
hr = metabase.Open ( wszInstancePath, METADATA_PERMISSION_WRITE );
if ( FAILED(hr) ) {
ErrorTraceX ( (LPARAM) this, "Failed to open instance key, %x", hr );
// !!!magnush - Should we return a simple Service doesn't exist error code?
// hr = NntpCreateExceptionFromWin32Error ( GetLastError () );
goto Exit;
}
// Does the client care if the key has changed?
if ( fFailIfChanged ) {
// Did the key change?
if ( HasKeyChanged ( pMetabase, metabase.QueryHandle(), &m_ftLastChanged ) ) {
StateTrace ( (LPARAM) this, "Metabase has changed, not setting properties" );
// !!!magnush - Return the appropriate error code:
hr = E_FAIL;
goto Exit;
}
}
// Extract the bindings:
hr = IBindingsToMDBindings ( m_pBindings, TRUE, &mszBindings );
BAIL_ON_FAILURE(hr);
hr = IBindingsToMDBindings ( m_pBindings, FALSE, &mszSecureBindings );
BAIL_ON_FAILURE(hr);
//
// The general procedure here is to keep setting metabase properties
// as long as nothing has gone wrong. This is done by short-circuiting
// the statement by ANDing it with the status code. This makes the code
// much more concise.
//
fRet = TRUE;
// Overridable server properties:
if ( m_bvChangedFields & CHNG_ARTICLETIMELIMIT ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ARTICLE_TIME_LIMIT, m_dwArticleTimeLimit );
}
if ( m_bvChangedFields & CHNG_HISTORYEXPIRATION ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_HISTORY_EXPIRATION, m_dwHistoryExpiration );
}
if ( m_bvChangedFields & CHNG_HONORCLIENTMSGIDS ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_HONOR_CLIENT_MSGIDS, m_fHonorClientMsgIDs );
}
if ( m_bvChangedFields & CHNG_SMTPSERVER ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SMTP_SERVER, m_strSmtpServer );
}
if ( m_bvChangedFields2 & CHNG2_ADMINEMAIL) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ADMIN_EMAIL, m_strAdminEmail );
}
if ( m_bvChangedFields & CHNG_ALLOWCLIENTPOSTS ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ALLOW_CLIENT_POSTS, m_fAllowClientPosts );
}
if ( m_bvChangedFields & CHNG_ALLOWFEEDPOSTS ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ALLOW_FEED_POSTS, m_fAllowFeedPosts );
}
if ( m_bvChangedFields & CHNG_ALLOWCONTROLMSGS ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ALLOW_CONTROL_MSGS, m_fAllowControlMsgs );
}
if ( m_bvChangedFields & CHNG_DEFAULTMODERATORDOMAIN ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_DEFAULT_MODERATOR, m_strDefaultModeratorDomain );
}
if ( m_bvChangedFields & CHNG_COMMANDLOGMASK ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_NNTP_COMMAND_LOG_MASK,m_dwCommandLogMask );
}
if ( m_bvChangedFields & CHNG_DISABLENEWNEWS ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_DISABLE_NEWNEWS, m_fDisableNewnews );
}
if ( m_bvChangedFields & CHNG_NEWSCRAWLERTIME ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_NEWS_CRAWLER_TIME, m_dwExpireRunFrequency );
}
if ( m_bvChangedFields & CHNG_SHUTDOWNLATENCY ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SHUTDOWN_LATENCY, m_dwShutdownLatency );
}
if ( m_bvChangedFields & CHNG_CLIENTPOSTHARDLIMIT ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_CLIENT_POST_HARD_LIMIT, m_dwClientPostHardLimit );
}
if ( m_bvChangedFields & CHNG_CLIENTPOSTSOFTLIMIT ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_CLIENT_POST_SOFT_LIMIT, m_dwClientPostSoftLimit );
}
if ( m_bvChangedFields & CHNG_FEEDPOSTHARDLIMIT ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_FEED_POST_HARD_LIMIT, m_dwFeedPostHardLimit );
}
if ( m_bvChangedFields & CHNG_FEEDPOSTSOFTLIMIT ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_FEED_POST_SOFT_LIMIT, m_dwFeedPostSoftLimit );
}
if ( m_bvChangedFields2 & CHNG2_ENABLELOGGING ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_LOG_TYPE, m_fEnableLogging );
}
// Service specific properties:
if ( m_bvChangedFields & CHNG_GROUPHELPFILE ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_GROUP_HELP_FILE, m_strGroupHelpFile );
}
if ( m_bvChangedFields & CHNG_GROUPLISTFILE ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_GROUP_LIST_FILE, m_strGroupListFile );
// BUGBUG: we share this change field, since Magnus didn't leave more space for
// change bit
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_GROUPVAR_LIST_FILE, m_strGroupVarListFile );
}
if ( m_bvChangedFields & CHNG_ARTICLETABLEFILE ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ARTICLE_TABLE_FILE, m_strArticleTableFile );
}
if ( m_bvChangedFields & CHNG_HISTORYTABLEFILE ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_HISTORY_TABLE_FILE, m_strHistoryTableFile );
}
if ( m_bvChangedFields & CHNG_MODERATORFILE ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_MODERATOR_FILE, m_strModeratorFile );
}
if ( m_bvChangedFields & CHNG_XOVERTABLEFILE ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_XOVER_TABLE_FILE, m_strXOverTableFile );
}
if ( m_bvChangedFields & CHNG_UUCPNAME ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_NNTP_UUCP_NAME, m_strUucpName );
}
if ( m_bvChangedFields & CHNG_ORGANIZATION ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_NNTP_ORGANIZATION, m_strOrganization );
}
if ( m_bvChangedFields & CHNG_AUTOSTART ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SERVER_AUTOSTART, m_fAutoStart );
}
if ( m_bvChangedFields & CHNG_COMMENT ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SERVER_COMMENT, m_strComment );
}
#if 0
if ( m_bvChangedFields & CHNG_SECUREPORT ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SECURE_PORT, m_dwSecurePort );
}
#endif
if ( m_bvChangedFields & CHNG_MAXCONNECTIONS ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_MAX_CONNECTIONS, m_dwMaxConnections );
}
if ( m_bvChangedFields2 & CHNG2_CONNECTIONTIMEOUT ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_CONNECTION_TIMEOUT, m_dwConnectionTimeout );
}
if ( m_bvChangedFields2 & CHNG2_ANONYMOUSUSERNAME ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ANONYMOUS_USER_NAME, m_strAnonymousUserName, _T(""), IIS_MD_UT_FILE );
}
if ( m_bvChangedFields2 & CHNG2_ANONYMOUSUSERPASS ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ANONYMOUS_PWD, m_strAnonymousUserPass, _T(""), IIS_MD_UT_FILE, METADATA_INHERIT | METADATA_SECURE );
}
if ( m_bvChangedFields2 & CHNG2_AUTOSYNCPASSWORD ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_ANONYMOUS_USE_SUBAUTH, m_fAutoSyncPassword, _T(""), IIS_MD_UT_FILE );
}
if ( m_bvChangedFields2 & CHNG2_PICKUPDIRECTORY ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_PICKUP_DIRECTORY, m_strPickupDirectory );
}
if ( m_bvChangedFields2 & CHNG2_FAILEDPICKUPDIRECTORY ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_FAILED_PICKUP_DIRECTORY, m_strFailedPickupDirectory );
}
if ( m_bvChangedFields2 & CHNG2_CLUSTERENABLED ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_CLUSTER_ENABLED, m_fClusterEnabled );
}
// if ( m_bvChangedFields & CHNG_AUTHORIZATION ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_AUTHORIZATION, m_bvAuthorization, _T(""), IIS_MD_UT_FILE );
// }
// if ( m_bvChangedFields & CHNG2_SSLACCESS ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SSL_ACCESS_PERM, m_bvSslAccess, _T(""), IIS_MD_UT_FILE );
// }
// if ( m_bvChangedFields & CHNG_NTAUTHENTICATION_PROVIDERS ) {
// fRet = fRet && StdPutMetabaseProp ( &metabase, MD_NTAUTHENTICATION_PROVIDERS, &m_mszProviders );
// }
// if ( m_bvChangedFields & CHNG_BINDINGS ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SERVER_BINDINGS, &mszBindings );
// }
// if ( m_bvChangedFields & CHNG_SECURE_BINDINGS ) {
fRet = fRet && StdPutMetabaseProp ( &metabase, MD_SECURE_BINDINGS, &mszSecureBindings );
// }
if ( m_bvChangedFields2 & CHNG2_ADMINACL ) {
if ( pSD ) {
if (fRet) {
hr = metabase.SetBinary ( MD_ADMIN_ACL, pSD, cbSD,
METADATA_INHERIT | METADATA_REFERENCE | METADATA_SECURE, IIS_MD_UT_FILE );
if (FAILED(hr)) {
fRet = FALSE;
goto Exit;
}
}
}
else {
pMetabase->DeleteData ( metabase.QueryHandle(), _T(""), MD_ADMIN_ACL, BINARY_METADATA );
}
}
// if ( m_bvChangedFields & CHNG_IPACCESS ) {
hr = m_pPrivateIpAccess->SendToMetabase ( &metabase );
BAIL_ON_FAILURE(hr);
// }
if ( !fRet ) {
hr = RETURNCODETOHRESULT ( GetLastError () );
goto Exit;
}
// Save the data to the metabase:
hr = metabase.Save ();
BAIL_ON_FAILURE(hr);
// Save the last changed time for this key:
m_ftLastChanged.dwHighDateTime = 0;
m_ftLastChanged.dwLowDateTime = 0;
hr = pMetabase->GetLastChangeTime ( metabase.QueryHandle(), _T(""), &m_ftLastChanged, FALSE );
if ( FAILED (hr) ) {
ErrorTraceX ( (LPARAM) this, "Failed to get last change time: %x", hr );
// Ignore this error.
hr = NOERROR;
}
Exit:
delete (char *) pSD;
TraceFunctLeave ();
return hr;
// MB automatically closes its handle
}
//$-------------------------------------------------------------------
//
// CNntpVirtualServer::ValidateStrings
//
// Description:
//
// Checks to make sure each string property is non-null.
//
// Returns:
//
// FALSE if any string property is NULL.
//
//--------------------------------------------------------------------
BOOL CNntpVirtualServer::ValidateStrings ( ) const
{
TraceFunctEnter ( "CNntpVirtualServer::ValidateStrings" );
// Check all property strings:
// If any string is NULL, return FALSE:
if (
!m_strSmtpServer ||
!m_strDefaultModeratorDomain ||
!m_strGroupHelpFile ||
!m_strGroupListFile ||
!m_strGroupVarListFile ||
!m_strArticleTableFile ||
!m_strHistoryTableFile ||
!m_strModeratorFile ||
!m_strXOverTableFile ||
!m_strUucpName ||
!m_strOrganization ||
!m_strComment ||
!m_strAnonymousUserName ||
!m_strAnonymousUserPass ||
!m_strPickupDirectory ||
!m_strFailedPickupDirectory
) {
ErrorTrace ( (LPARAM) this, "String validation failed" );
TraceFunctLeave ();
return FALSE;
}
_ASSERT ( IS_VALID_STRING ( m_strSmtpServer ) );
_ASSERT ( IS_VALID_STRING ( m_strDefaultModeratorDomain ) );
_ASSERT ( IS_VALID_STRING ( m_strGroupHelpFile ) );
_ASSERT ( IS_VALID_STRING ( m_strGroupListFile ) );
_ASSERT ( IS_VALID_STRING ( m_strGroupVarListFile ) );
_ASSERT ( IS_VALID_STRING ( m_strArticleTableFile ) );
_ASSERT ( IS_VALID_STRING ( m_strHistoryTableFile ) );
_ASSERT ( IS_VALID_STRING ( m_strModeratorFile ) );
_ASSERT ( IS_VALID_STRING ( m_strXOverTableFile ) );
_ASSERT ( IS_VALID_STRING ( m_strUucpName ) );
_ASSERT ( IS_VALID_STRING ( m_strOrganization ) );
_ASSERT ( IS_VALID_STRING ( m_strComment ) );
_ASSERT ( IS_VALID_STRING ( m_strAnonymousUserName ) );
_ASSERT ( IS_VALID_STRING ( m_strAnonymousUserPass ) );
_ASSERT ( IS_VALID_STRING ( m_strPickupDirectory ) );
_ASSERT ( IS_VALID_STRING ( m_strFailedPickupDirectory ) );
TraceFunctLeave ();
return TRUE;
}
//$-------------------------------------------------------------------
//
// CNntpVirtualServer::ValidateProperties
//
// Description:
//
// Checks to make sure all parameters are valid.
//
// Parameters:
//
// pErr - resulting error code.
//
// Returns:
//
// FALSE if any property was not valid. In this case pErr
// will contain an error that describes the invalid condition.
//
//--------------------------------------------------------------------
BOOL CNntpVirtualServer::ValidateProperties ( ) const
{
BOOL fRet = TRUE;
_ASSERT ( ValidateStrings () );
fRet = fRet && PV_MinMax ( m_dwArticleTimeLimit, MIN_ARTICLETIMELIMIT, MAX_ARTICLETIMELIMIT );
fRet = fRet && PV_MinMax ( m_dwHistoryExpiration, MIN_HISTORYEXPIRATION, MAX_HISTORYEXPIRATION );
fRet = fRet && PV_Boolean ( m_fHonorClientMsgIDs );
fRet = fRet && PV_MaxChars ( m_strSmtpServer, MAXLEN_SMTPSERVER );
fRet = fRet && PV_Boolean ( m_fAllowClientPosts );
fRet = fRet && PV_Boolean ( m_fAllowFeedPosts );
fRet = fRet && PV_Boolean ( m_fAllowControlMsgs );
fRet = fRet && PV_MaxChars ( m_strDefaultModeratorDomain, MAXLEN_DEFAULTMODERATORDOMAIN );
fRet = fRet && PV_MinMax ( m_dwCommandLogMask, MIN_COMMANDLOGMASK, MAX_COMMANDLOGMASK );
fRet = fRet && PV_Boolean ( m_fDisableNewnews );
fRet = fRet && PV_MinMax ( m_dwExpireRunFrequency, MIN_NEWSCRAWLERTIME, MAX_NEWSCRAWLERTIME );
fRet = fRet && PV_MinMax ( m_dwShutdownLatency, MIN_SHUTDOWNLATENCY, MAX_SHUTDOWNLATENCY );
fRet = fRet && PV_Boolean ( m_fAutoStart );
fRet = fRet && PV_Boolean ( m_fClusterEnabled );
return fRet;
}
void CNntpVirtualServer::CorrectProperties ( )
{
if ( m_strServer && !PV_MaxChars ( m_strServer, MAXLEN_SERVER ) ) {
m_strServer[ MAXLEN_SERVER - 1 ] = NULL;
}
if ( !PV_MinMax ( m_dwArticleTimeLimit, MIN_ARTICLETIMELIMIT, MAX_ARTICLETIMELIMIT ) ) {
m_dwArticleTimeLimit = NNTP_DEF_ARTICLETIMELIMIT;
}
if ( !PV_MinMax ( m_dwHistoryExpiration, MIN_HISTORYEXPIRATION, MAX_HISTORYEXPIRATION ) ) {
m_dwHistoryExpiration = NNTP_DEF_HISTORYEXPIRATION;
}
if ( !PV_Boolean ( m_fHonorClientMsgIDs ) ) {
m_fHonorClientMsgIDs = !!m_fHonorClientMsgIDs;
}
if ( !PV_MaxChars ( m_strSmtpServer, MAXLEN_SMTPSERVER ) ) {
m_strSmtpServer[ MAXLEN_SMTPSERVER - 1 ] = NULL;
}
if ( !PV_Boolean ( m_fAllowClientPosts ) ) {
m_fAllowClientPosts = !!m_fAllowClientPosts;
}
if ( !PV_Boolean ( m_fAllowFeedPosts ) ) {
m_fAllowFeedPosts = !!m_fAllowFeedPosts;
}
if ( !PV_Boolean ( m_fAllowControlMsgs ) ) {
m_fAllowControlMsgs = !!m_fAllowControlMsgs;
}
if ( !PV_MaxChars ( m_strDefaultModeratorDomain, MAXLEN_DEFAULTMODERATORDOMAIN ) ) {
m_strDefaultModeratorDomain[ MAXLEN_DEFAULTMODERATORDOMAIN - 1] = NULL;
}
if ( !PV_MinMax ( m_dwCommandLogMask, MIN_COMMANDLOGMASK, MAX_COMMANDLOGMASK ) ) {
m_dwCommandLogMask = NNTP_DEF_COMMANDLOGMASK;
}
if ( !PV_Boolean ( m_fDisableNewnews ) ) {
m_fDisableNewnews = !!m_fDisableNewnews;
}
if ( !PV_MinMax ( m_dwExpireRunFrequency, MIN_NEWSCRAWLERTIME, MAX_NEWSCRAWLERTIME ) ) {
m_dwExpireRunFrequency = NNTP_DEF_NEWSCRAWLERTIME;
}
if ( !PV_MinMax ( m_dwShutdownLatency, MIN_SHUTDOWNLATENCY, MAX_SHUTDOWNLATENCY ) ) {
m_dwShutdownLatency = NNTP_DEF_SHUTDOWNLATENCY;
}
if ( !PV_Boolean ( m_fAutoStart ) ) {
m_fAutoStart = !!m_fAutoStart;
}
if ( !PV_Boolean ( m_fClusterEnabled ) ) {
m_fClusterEnabled = !!m_fClusterEnabled;
}
_ASSERT ( ValidateProperties ( ) );
}
NNTP_SERVER_STATE CNntpVirtualServer::TranslateServerState ( DWORD dwState )
{
NNTP_SERVER_STATE result = NNTP_SERVER_STATE_UNKNOWN;
switch ( dwState ) {
case MD_SERVER_STATE_STARTING:
result = NNTP_SERVER_STATE_STARTING;
break;
case MD_SERVER_STATE_STARTED:
result = NNTP_SERVER_STATE_STARTED;
break;
case MD_SERVER_STATE_STOPPING:
result = NNTP_SERVER_STATE_STOPPING;
break;
case MD_SERVER_STATE_STOPPED:
result = NNTP_SERVER_STATE_STOPPED;
break;
case MD_SERVER_STATE_PAUSING:
result = NNTP_SERVER_STATE_PAUSING;
break;
case MD_SERVER_STATE_PAUSED:
result = NNTP_SERVER_STATE_PAUSED;
break;
case MD_SERVER_STATE_CONTINUING:
result = NNTP_SERVER_STATE_CONTINUING;
break;
case MD_SERVER_STATE_INVALID:
result = NNTP_SERVER_STATE_UNKNOWN;
break;
default:
_ASSERT ( FALSE );
break;
}
return result;
}
HRESULT AclToAdministrators ( LPCTSTR strServer, PSECURITY_DESCRIPTOR pSDRelative, SAFEARRAY ** ppsaAdmins )
{
HRESULT hr = NOERROR;
SAFEARRAY * psaResult = NULL;
SAFEARRAYBOUND rgsaBound[1];
DWORD cbAcl;
long cValidAdmins;
long cAdmins;
long i;
long iValid;
PSECURITY_DESCRIPTOR pSD = NULL;
PACL pAcl;
BOOL fDaclPresent;
BOOL fDaclDef;
pSD = (PSECURITY_DESCRIPTOR)pSDRelative;
if (pSD == NULL)
{
//
// Empty...
//
return ERROR_SUCCESS;
}
if (!IsValidSecurityDescriptor(pSD))
{
return GetLastError();
}
_VERIFY(GetSecurityDescriptorDacl(pSD, &fDaclPresent, &pAcl, &fDaclDef));
if (!fDaclPresent || pAcl == NULL)
{
return ERROR_SUCCESS;
}
if (!IsValidAcl(pAcl))
{
return GetLastError();
}
cAdmins = pAcl->AceCount;
cbAcl = pAcl->AclSize;
//
// Count valid Acls:
//
for ( cValidAdmins = 0, i = 0; i < cAdmins; i++ ) {
PVOID pAce;
PACE_HEADER pAceHeader;
if ( GetAce(pAcl, i, &pAce) ) {
pAceHeader = (PACE_HEADER)pAce;
if ( pAceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE ) {
ACCESS_MASK AccessMask;
AccessMask = ((PACCESS_ALLOWED_ACE)pAce)->Mask;
if ( AccessMask & FILE_GENERIC_WRITE ) {
// Only count admins with write access.
cValidAdmins++;
}
}
}
}
rgsaBound[0].lLbound = 0;
rgsaBound[0].cElements = cValidAdmins;
psaResult = SafeArrayCreate ( VT_BSTR, 1, rgsaBound );
if ( !psaResult ) {
BAIL_WITH_FAILURE ( hr, E_OUTOFMEMORY );
}
for ( iValid = 0, i = 0; i < cAdmins; i++ ) {
PVOID pAce;
PACE_HEADER pAceHeader;
PSID pSID;
if ( GetAce(pAcl, i, &pAce) ) {
pAceHeader = (PACE_HEADER)pAce;
if ( pAceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE ) {
ACCESS_MASK AccessMask;
AccessMask = ((PACCESS_ALLOWED_ACE)pAce)->Mask;
if ( AccessMask & FILE_GENERIC_WRITE ) {
CComBSTR str;
pSID = (PSID)&((PACCESS_ALLOWED_ACE)pAce)->SidStart;
hr = SidToString ( strServer, pSID, &str );
BAIL_ON_FAILURE(hr);
hr = SafeArrayPutElement ( psaResult, &iValid, (PVOID) str );
BAIL_ON_FAILURE(hr);
iValid++;
}
}
}
}
if ( *ppsaAdmins ) {
SafeArrayDestroy ( *ppsaAdmins );
}
*ppsaAdmins = psaResult;
Exit:
return hr;
}
PSID
GetOwnerSID()
/*++
Routine Description:
Arguments:
Return Value:
Owner sid
--*/
{
PSID pSID = NULL;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(
&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pSID))
{
_ASSERT( 0 );
//TRACEEOLID("Unable to get primary SID " << ::GetLastError());
}
return pSID;
}
HRESULT AdministratorsToAcl (
LPCTSTR strServer,
SAFEARRAY * psaAdmins,
PSECURITY_DESCRIPTOR* ppSD,
DWORD * pcbSD
)
{
HRESULT hr = NOERROR;
long lBound;
long uBound;
long i;
BOOL fRet;
DWORD cbAcl;
PACL pAclResult = NULL;
PSID pSID;
*ppSD = NULL;
*pcbSD = 0;
if ( psaAdmins == NULL ) {
lBound = 0;
uBound = -1;
}
else {
SafeArrayGetLBound ( psaAdmins, 1, &lBound );
SafeArrayGetUBound ( psaAdmins, 1, &uBound );
}
// Do we have an array of Domain\Usernames?
if ( lBound > uBound ) {
// Nothing in the array, so the ACL is NULL.
goto Exit;
}
//
// Calculate ACL size:
//
cbAcl = sizeof (ACL);
for ( i = lBound; i <= uBound ; i++ ) {
CComBSTR str;
pSID = NULL;
SafeArrayGetElement ( psaAdmins, &i, &str );
hr = StringToSid ( strServer, str, &pSID );
if ( SUCCEEDED(hr) && IsValidSid(pSID)) {
cbAcl += GetLengthSid ( pSID );
cbAcl += sizeof ( ACCESS_ALLOWED_ACE );
cbAcl -= sizeof (DWORD);
}
hr = NOERROR;
delete pSID;
}
pAclResult = (PACL) new char [ cbAcl ];
if ( !pAclResult ) {
BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
}
fRet = InitializeAcl ( pAclResult, cbAcl, ACL_REVISION );
_ASSERT ( fRet );
if ( !fRet ) {
BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT(GetLastError() ) );
}
//
// Create ACL:
//
for ( i = lBound; i <= uBound; i++ ) {
CComBSTR str;
PSID pSID;
pSID = NULL;
SafeArrayGetElement ( psaAdmins, &i, &str );
hr = StringToSid ( strServer, str, &pSID );
if ( SUCCEEDED(hr) ) {
fRet = AddAccessAllowedAce (
pAclResult,
ACL_REVISION,
FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE,
pSID
);
if ( !fRet ) {
BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT(GetLastError() ) );
}
}
hr = NOERROR;
delete pSID;
}
//
// Build the security descriptor
//
PSECURITY_DESCRIPTOR pSD;
pSD = new char[SECURITY_DESCRIPTOR_MIN_LENGTH];
_VERIFY(InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION));
_VERIFY(SetSecurityDescriptorDacl(pSD, TRUE, pAclResult, FALSE));
//
// Set owner and primary group
//
pSID = GetOwnerSID();
_ASSERT(pSID);
_VERIFY(SetSecurityDescriptorOwner(pSD, pSID, TRUE));
_VERIFY(SetSecurityDescriptorGroup(pSD, pSID, TRUE));
//
// Convert to self-relative
//
PSECURITY_DESCRIPTOR pSDSelfRelative;
pSDSelfRelative = NULL;
DWORD dwSize;
dwSize = 0L;
MakeSelfRelativeSD(pSD, pSDSelfRelative, &dwSize);
pSDSelfRelative = new char[dwSize];
MakeSelfRelativeSD(pSD, pSDSelfRelative, &dwSize);
//
// Clean up
//
delete (char*)pSD;
FreeSid( pSID );
_ASSERT ( SUCCEEDED(hr) );
*ppSD = pSDSelfRelative;
*pcbSD = dwSize;
Exit:
if ( FAILED(hr) ) {
delete pAclResult;
}
return hr;
}
HRESULT SidToString ( LPCWSTR strSystemName, PSID pSID, BSTR * pStr )
{
HRESULT hr = NOERROR;
BOOL fLookup;
SID_NAME_USE SidToNameUse;
WCHAR wszUsername [ PATHLEN ];
DWORD cbUsername = sizeof ( wszUsername );
WCHAR wszDomain [ PATHLEN ];
DWORD cbDomain = sizeof ( wszDomain );
WCHAR wszResult [ 2 * PATHLEN + 2 ];
LPWSTR pwszSid = NULL;
fLookup = LookupAccountSid (
strSystemName,
pSID,
wszUsername,
&cbUsername,
wszDomain,
&cbDomain,
&SidToNameUse
);
if ( !fLookup && GetLastError() != ERROR_NONE_MAPPED) {
BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT (GetLastError ()) );
}
if (fLookup) {
wsprintf ( wszResult, _T("%s\\%s"), wszDomain, wszUsername );
} else {
// Couldn't get the username. Convert it to a string of the form .\S-1-5-xxx
if (!ConvertSidToStringSid(pSID, &pwszSid)) {
BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT (GetLastError ()) );
}
wsprintf(wszResult, _T(".\\%s"), pwszSid);
}
*pStr = ::SysAllocString ( wszResult );
if (*pStr == NULL)
hr = E_OUTOFMEMORY;
Exit:
if (pwszSid) {
LocalFree(pwszSid);
}
return hr;
}
HRESULT StringToSid ( LPCWSTR strSystemName, LPWSTR str, PSID * ppSID )
{
HRESULT hr = NOERROR;
BOOL fLookup;
WCHAR wszRefDomain[PATHLEN];
DWORD cbRefDomain = sizeof ( wszRefDomain );
DWORD cbSid = 0;
SID_NAME_USE SidNameUse;
BOOL fIsSID = FALSE;
PSID pSID = NULL;
*ppSID = NULL;
//
// If the string starts with .\, then a SID follows rather than a domain\user
//
if (str[0] == L'.' && str[1] == L'\\') {
fIsSID = TRUE;
str+=2;
}
if ( str[0] == '\\' ) {
//
// Skip the initial \, this is for BUILTIN usernames:
//
str++;
}
_ASSERT ( str[0] != '\\' );
if (fIsSID) {
if (!ConvertStringSidToSid(str, &pSID))
BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT(GetLastError()));
cbSid = GetLengthSid(pSID);
*ppSID = (LPVOID) new char [ cbSid ];
if ( !*ppSID ) {
BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
}
memcpy(*ppSID, pSID, cbSid);
} else {
fLookup = LookupAccountName (
strSystemName,
str,
*ppSID,
&cbSid,
wszRefDomain,
&cbRefDomain,
&SidNameUse
);
// First lookup will fail, but the size will be right:
if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) {
BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT ( GetLastError () ) );
}
*ppSID = (LPVOID) new char [ cbSid ];
if ( !*ppSID ) {
BAIL_WITH_FAILURE(hr, E_OUTOFMEMORY);
}
fLookup = LookupAccountName (
strSystemName,
str,
*ppSID,
&cbSid,
wszRefDomain,
&cbRefDomain,
&SidNameUse
);
}
if ( !fLookup ) {
BAIL_WITH_FAILURE(hr, RETURNCODETOHRESULT ( GetLastError () ) );
}
Exit:
if (pSID) {
LocalFree(pSID);
}
return hr;
}